generated_message_reflection.cc revision d0332953cda33fb4f8e24ebff9c49159b69c43d6
1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// http://code.google.com/p/protobuf/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9//     * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11//     * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15//     * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// Author: kenton@google.com (Kenton Varda)
32//  Based on original Protocol Buffers design by
33//  Sanjay Ghemawat, Jeff Dean, and others.
34
35#include <algorithm>
36#include <google/protobuf/generated_message_reflection.h>
37#include <google/protobuf/descriptor.h>
38#include <google/protobuf/descriptor.pb.h>
39#include <google/protobuf/repeated_field.h>
40#include <google/protobuf/extension_set.h>
41#include <google/protobuf/generated_message_util.h>
42#include <google/protobuf/stubs/common.h>
43
44namespace google {
45namespace protobuf {
46namespace internal {
47
48namespace { const string kEmptyString; }
49
50int StringSpaceUsedExcludingSelf(const string& str) {
51  const void* start = &str;
52  const void* end = &str + 1;
53
54  if (start <= str.data() && str.data() <= end) {
55    // The string's data is stored inside the string object itself.
56    return 0;
57  } else {
58    return str.capacity();
59  }
60}
61
62bool ParseNamedEnum(const EnumDescriptor* descriptor,
63                    const string& name,
64                    int* value) {
65  const EnumValueDescriptor* d = descriptor->FindValueByName(name);
66  if (d == NULL) return false;
67  *value = d->number();
68  return true;
69}
70
71const string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
72  static string kEmptyString;
73  const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
74  return (d == NULL ? kEmptyString : d->name());
75}
76
77// ===================================================================
78// Helpers for reporting usage errors (e.g. trying to use GetInt32() on
79// a string field).
80
81namespace {
82
83void ReportReflectionUsageError(
84    const Descriptor* descriptor, const FieldDescriptor* field,
85    const char* method, const char* description) {
86  GOOGLE_LOG(FATAL)
87    << "Protocol Buffer reflection usage error:\n"
88       "  Method      : google::protobuf::Reflection::" << method << "\n"
89       "  Message type: " << descriptor->full_name() << "\n"
90       "  Field       : " << field->full_name() << "\n"
91       "  Problem     : " << description;
92}
93
94const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = {
95  "INVALID_CPPTYPE",
96  "CPPTYPE_INT32",
97  "CPPTYPE_INT64",
98  "CPPTYPE_UINT32",
99  "CPPTYPE_UINT64",
100  "CPPTYPE_DOUBLE",
101  "CPPTYPE_FLOAT",
102  "CPPTYPE_BOOL",
103  "CPPTYPE_ENUM",
104  "CPPTYPE_STRING",
105  "CPPTYPE_MESSAGE"
106};
107
108static void ReportReflectionUsageTypeError(
109    const Descriptor* descriptor, const FieldDescriptor* field,
110    const char* method,
111    FieldDescriptor::CppType expected_type) {
112  GOOGLE_LOG(FATAL)
113    << "Protocol Buffer reflection usage error:\n"
114       "  Method      : google::protobuf::Reflection::" << method << "\n"
115       "  Message type: " << descriptor->full_name() << "\n"
116       "  Field       : " << field->full_name() << "\n"
117       "  Problem     : Field is not the right type for this message:\n"
118       "    Expected  : " << cpptype_names_[expected_type] << "\n"
119       "    Field type: " << cpptype_names_[field->cpp_type()];
120}
121
122static void ReportReflectionUsageEnumTypeError(
123    const Descriptor* descriptor, const FieldDescriptor* field,
124    const char* method, const EnumValueDescriptor* value) {
125  GOOGLE_LOG(FATAL)
126    << "Protocol Buffer reflection usage error:\n"
127       "  Method      : google::protobuf::Reflection::" << method << "\n"
128       "  Message type: " << descriptor->full_name() << "\n"
129       "  Field       : " << field->full_name() << "\n"
130       "  Problem     : Enum value did not match field type:\n"
131       "    Expected  : " << field->enum_type()->full_name() << "\n"
132       "    Actual    : " << value->full_name();
133}
134
135#define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION)                      \
136  if (!(CONDITION))                                                            \
137    ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION)
138#define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION)                        \
139  USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION)
140#define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION)                        \
141  USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION)
142
143#define USAGE_CHECK_TYPE(METHOD, CPPTYPE)                                      \
144  if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE)                 \
145    ReportReflectionUsageTypeError(descriptor_, field, #METHOD,                \
146                                   FieldDescriptor::CPPTYPE_##CPPTYPE)
147
148#define USAGE_CHECK_ENUM_VALUE(METHOD)                                         \
149  if (value->type() != field->enum_type())                                     \
150    ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value)
151
152#define USAGE_CHECK_MESSAGE_TYPE(METHOD)                                       \
153  USAGE_CHECK_EQ(field->containing_type(), descriptor_,                        \
154                 METHOD, "Field does not match message type.");
155#define USAGE_CHECK_SINGULAR(METHOD)                                           \
156  USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD,      \
157                 "Field is repeated; the method requires a singular field.")
158#define USAGE_CHECK_REPEATED(METHOD)                                           \
159  USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD,      \
160                 "Field is singular; the method requires a repeated field.")
161
162#define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE)                       \
163    USAGE_CHECK_MESSAGE_TYPE(METHOD);                                 \
164    USAGE_CHECK_##LABEL(METHOD);                                      \
165    USAGE_CHECK_TYPE(METHOD, CPPTYPE)
166
167}  // namespace
168
169// ===================================================================
170
171GeneratedMessageReflection::GeneratedMessageReflection(
172    const Descriptor* descriptor,
173    const Message* default_instance,
174    const int offsets[],
175    int has_bits_offset,
176    int unknown_fields_offset,
177    int extensions_offset,
178    const DescriptorPool* descriptor_pool,
179    MessageFactory* factory,
180    int object_size)
181  : descriptor_       (descriptor),
182    default_instance_ (default_instance),
183    offsets_          (offsets),
184    has_bits_offset_  (has_bits_offset),
185    unknown_fields_offset_(unknown_fields_offset),
186    extensions_offset_(extensions_offset),
187    object_size_      (object_size),
188    descriptor_pool_  ((descriptor_pool == NULL) ?
189                         DescriptorPool::generated_pool() :
190                         descriptor_pool),
191    message_factory_  (factory) {
192}
193
194GeneratedMessageReflection::~GeneratedMessageReflection() {}
195
196const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields(
197    const Message& message) const {
198  const void* ptr = reinterpret_cast<const uint8*>(&message) +
199                    unknown_fields_offset_;
200  return *reinterpret_cast<const UnknownFieldSet*>(ptr);
201}
202UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields(
203    Message* message) const {
204  void* ptr = reinterpret_cast<uint8*>(message) + unknown_fields_offset_;
205  return reinterpret_cast<UnknownFieldSet*>(ptr);
206}
207
208int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
209  // object_size_ already includes the in-memory representation of each field
210  // in the message, so we only need to account for additional memory used by
211  // the fields.
212  int total_size = object_size_;
213
214  total_size += GetUnknownFields(message).SpaceUsedExcludingSelf();
215
216  if (extensions_offset_ != -1) {
217    total_size += GetExtensionSet(message).SpaceUsedExcludingSelf();
218  }
219
220  for (int i = 0; i < descriptor_->field_count(); i++) {
221    const FieldDescriptor* field = descriptor_->field(i);
222
223    if (field->is_repeated()) {
224      switch (field->cpp_type()) {
225#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
226        case FieldDescriptor::CPPTYPE_##UPPERCASE :                           \
227          total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field)     \
228                          .SpaceUsedExcludingSelf();                          \
229          break
230
231        HANDLE_TYPE( INT32,  int32);
232        HANDLE_TYPE( INT64,  int64);
233        HANDLE_TYPE(UINT32, uint32);
234        HANDLE_TYPE(UINT64, uint64);
235        HANDLE_TYPE(DOUBLE, double);
236        HANDLE_TYPE( FLOAT,  float);
237        HANDLE_TYPE(  BOOL,   bool);
238        HANDLE_TYPE(  ENUM,    int);
239#undef HANDLE_TYPE
240
241        case FieldDescriptor::CPPTYPE_STRING:
242          switch (field->options().ctype()) {
243            default:  // TODO(kenton):  Support other string reps.
244            case FieldOptions::STRING:
245              total_size += GetRaw<RepeatedPtrField<string> >(message, field)
246                              .SpaceUsedExcludingSelf();
247              break;
248          }
249          break;
250
251        case FieldDescriptor::CPPTYPE_MESSAGE:
252          // We don't know which subclass of RepeatedPtrFieldBase the type is,
253          // so we use RepeatedPtrFieldBase directly.
254          total_size +=
255              GetRaw<RepeatedPtrFieldBase>(message, field)
256                .SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
257          break;
258      }
259    } else {
260      switch (field->cpp_type()) {
261        case FieldDescriptor::CPPTYPE_INT32 :
262        case FieldDescriptor::CPPTYPE_INT64 :
263        case FieldDescriptor::CPPTYPE_UINT32:
264        case FieldDescriptor::CPPTYPE_UINT64:
265        case FieldDescriptor::CPPTYPE_DOUBLE:
266        case FieldDescriptor::CPPTYPE_FLOAT :
267        case FieldDescriptor::CPPTYPE_BOOL  :
268        case FieldDescriptor::CPPTYPE_ENUM  :
269          // Field is inline, so we've already counted it.
270          break;
271
272        case FieldDescriptor::CPPTYPE_STRING: {
273          switch (field->options().ctype()) {
274            default:  // TODO(kenton):  Support other string reps.
275            case FieldOptions::STRING: {
276              const string* ptr = GetField<const string*>(message, field);
277
278              // Initially, the string points to the default value stored in
279              // the prototype. Only count the string if it has been changed
280              // from the default value.
281              const string* default_ptr = DefaultRaw<const string*>(field);
282
283              if (ptr != default_ptr) {
284                // string fields are represented by just a pointer, so also
285                // include sizeof(string) as well.
286                total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr);
287              }
288              break;
289            }
290          }
291          break;
292        }
293
294        case FieldDescriptor::CPPTYPE_MESSAGE:
295          if (&message == default_instance_) {
296            // For singular fields, the prototype just stores a pointer to the
297            // external type's prototype, so there is no extra memory usage.
298          } else {
299            const Message* sub_message = GetRaw<const Message*>(message, field);
300            if (sub_message != NULL) {
301              total_size += sub_message->SpaceUsed();
302            }
303          }
304          break;
305      }
306    }
307  }
308
309  return total_size;
310}
311
312void GeneratedMessageReflection::Swap(
313    Message* message1,
314    Message* message2) const {
315  if (message1 == message2) return;
316
317  // TODO(kenton):  Other Reflection methods should probably check this too.
318  GOOGLE_CHECK_EQ(message1->GetReflection(), this)
319    << "First argument to Swap() (of type \""
320    << message1->GetDescriptor()->full_name()
321    << "\") is not compatible with this reflection object (which is for type \""
322    << descriptor_->full_name()
323    << "\").  Note that the exact same class is required; not just the same "
324       "descriptor.";
325  GOOGLE_CHECK_EQ(message2->GetReflection(), this)
326    << "Second argument to Swap() (of type \""
327    << message1->GetDescriptor()->full_name()
328    << "\") is not compatible with this reflection object (which is for type \""
329    << descriptor_->full_name()
330    << "\").  Note that the exact same class is required; not just the same "
331       "descriptor.";
332
333  uint32* has_bits1 = MutableHasBits(message1);
334  uint32* has_bits2 = MutableHasBits(message2);
335  int has_bits_size = (descriptor_->field_count() + 31) / 32;
336
337  for (int i = 0; i < has_bits_size; i++) {
338    std::swap(has_bits1[i], has_bits2[i]);
339  }
340
341  for (int i = 0; i < descriptor_->field_count(); i++) {
342    const FieldDescriptor* field = descriptor_->field(i);
343    if (field->is_repeated()) {
344      switch (field->cpp_type()) {
345#define SWAP_ARRAYS(CPPTYPE, TYPE)                                           \
346        case FieldDescriptor::CPPTYPE_##CPPTYPE:                             \
347          MutableRaw<RepeatedField<TYPE> >(message1, field)->Swap(           \
348              MutableRaw<RepeatedField<TYPE> >(message2, field));            \
349          break;
350
351          SWAP_ARRAYS(INT32 , int32 );
352          SWAP_ARRAYS(INT64 , int64 );
353          SWAP_ARRAYS(UINT32, uint32);
354          SWAP_ARRAYS(UINT64, uint64);
355          SWAP_ARRAYS(FLOAT , float );
356          SWAP_ARRAYS(DOUBLE, double);
357          SWAP_ARRAYS(BOOL  , bool  );
358          SWAP_ARRAYS(ENUM  , int   );
359#undef SWAP_ARRAYS
360
361        case FieldDescriptor::CPPTYPE_STRING:
362        case FieldDescriptor::CPPTYPE_MESSAGE:
363          MutableRaw<RepeatedPtrFieldBase>(message1, field)->Swap(
364              MutableRaw<RepeatedPtrFieldBase>(message2, field));
365          break;
366
367        default:
368          GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
369      }
370    } else {
371      switch (field->cpp_type()) {
372#define SWAP_VALUES(CPPTYPE, TYPE)                                           \
373        case FieldDescriptor::CPPTYPE_##CPPTYPE:                             \
374          std::swap(*MutableRaw<TYPE>(message1, field),                      \
375                    *MutableRaw<TYPE>(message2, field));                     \
376          break;
377
378          SWAP_VALUES(INT32 , int32 );
379          SWAP_VALUES(INT64 , int64 );
380          SWAP_VALUES(UINT32, uint32);
381          SWAP_VALUES(UINT64, uint64);
382          SWAP_VALUES(FLOAT , float );
383          SWAP_VALUES(DOUBLE, double);
384          SWAP_VALUES(BOOL  , bool  );
385          SWAP_VALUES(ENUM  , int   );
386          SWAP_VALUES(MESSAGE, Message*);
387#undef SWAP_VALUES
388
389        case FieldDescriptor::CPPTYPE_STRING:
390          switch (field->options().ctype()) {
391            default:  // TODO(kenton):  Support other string reps.
392            case FieldOptions::STRING:
393              std::swap(*MutableRaw<string*>(message1, field),
394                        *MutableRaw<string*>(message2, field));
395              break;
396          }
397          break;
398
399        default:
400          GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
401      }
402    }
403  }
404
405  if (extensions_offset_ != -1) {
406    MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
407  }
408
409  MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
410}
411
412// -------------------------------------------------------------------
413
414bool GeneratedMessageReflection::HasField(const Message& message,
415                                          const FieldDescriptor* field) const {
416  USAGE_CHECK_MESSAGE_TYPE(HasField);
417  USAGE_CHECK_SINGULAR(HasField);
418
419  if (field->is_extension()) {
420    return GetExtensionSet(message).Has(field->number());
421  } else {
422    return HasBit(message, field);
423  }
424}
425
426int GeneratedMessageReflection::FieldSize(const Message& message,
427                                          const FieldDescriptor* field) const {
428  USAGE_CHECK_MESSAGE_TYPE(FieldSize);
429  USAGE_CHECK_REPEATED(FieldSize);
430
431  if (field->is_extension()) {
432    return GetExtensionSet(message).ExtensionSize(field->number());
433  } else {
434    switch (field->cpp_type()) {
435#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
436      case FieldDescriptor::CPPTYPE_##UPPERCASE :                             \
437        return GetRaw<RepeatedField<LOWERCASE> >(message, field).size()
438
439      HANDLE_TYPE( INT32,  int32);
440      HANDLE_TYPE( INT64,  int64);
441      HANDLE_TYPE(UINT32, uint32);
442      HANDLE_TYPE(UINT64, uint64);
443      HANDLE_TYPE(DOUBLE, double);
444      HANDLE_TYPE( FLOAT,  float);
445      HANDLE_TYPE(  BOOL,   bool);
446      HANDLE_TYPE(  ENUM,    int);
447#undef HANDLE_TYPE
448
449      case FieldDescriptor::CPPTYPE_STRING:
450      case FieldDescriptor::CPPTYPE_MESSAGE:
451        return GetRaw<RepeatedPtrFieldBase>(message, field).size();
452    }
453
454    GOOGLE_LOG(FATAL) << "Can't get here.";
455    return 0;
456  }
457}
458
459void GeneratedMessageReflection::ClearField(
460    Message* message, const FieldDescriptor* field) const {
461  USAGE_CHECK_MESSAGE_TYPE(ClearField);
462
463  if (field->is_extension()) {
464    MutableExtensionSet(message)->ClearExtension(field->number());
465  } else if (!field->is_repeated()) {
466    if (HasBit(*message, field)) {
467      ClearBit(message, field);
468
469      // We need to set the field back to its default value.
470      switch (field->cpp_type()) {
471#define CLEAR_TYPE(CPPTYPE, TYPE)                                            \
472        case FieldDescriptor::CPPTYPE_##CPPTYPE:                             \
473          *MutableRaw<TYPE>(message, field) =                                \
474            field->default_value_##TYPE();                                   \
475          break;
476
477        CLEAR_TYPE(INT32 , int32 );
478        CLEAR_TYPE(INT64 , int64 );
479        CLEAR_TYPE(UINT32, uint32);
480        CLEAR_TYPE(UINT64, uint64);
481        CLEAR_TYPE(FLOAT , float );
482        CLEAR_TYPE(DOUBLE, double);
483        CLEAR_TYPE(BOOL  , bool  );
484#undef CLEAR_TYPE
485
486        case FieldDescriptor::CPPTYPE_ENUM:
487          *MutableRaw<int>(message, field) =
488            field->default_value_enum()->number();
489          break;
490
491        case FieldDescriptor::CPPTYPE_STRING: {
492          switch (field->options().ctype()) {
493            default:  // TODO(kenton):  Support other string reps.
494            case FieldOptions::STRING:
495              const string* default_ptr = DefaultRaw<const string*>(field);
496              string** value = MutableRaw<string*>(message, field);
497              if (*value != default_ptr) {
498                if (field->has_default_value()) {
499                  (*value)->assign(field->default_value_string());
500                } else {
501                  (*value)->clear();
502                }
503              }
504              break;
505          }
506          break;
507        }
508
509        case FieldDescriptor::CPPTYPE_MESSAGE:
510          (*MutableRaw<Message*>(message, field))->Clear();
511          break;
512      }
513    }
514  } else {
515    switch (field->cpp_type()) {
516#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
517      case FieldDescriptor::CPPTYPE_##UPPERCASE :                             \
518        MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear();       \
519        break
520
521      HANDLE_TYPE( INT32,  int32);
522      HANDLE_TYPE( INT64,  int64);
523      HANDLE_TYPE(UINT32, uint32);
524      HANDLE_TYPE(UINT64, uint64);
525      HANDLE_TYPE(DOUBLE, double);
526      HANDLE_TYPE( FLOAT,  float);
527      HANDLE_TYPE(  BOOL,   bool);
528      HANDLE_TYPE(  ENUM,    int);
529#undef HANDLE_TYPE
530
531      case FieldDescriptor::CPPTYPE_STRING: {
532        switch (field->options().ctype()) {
533          default:  // TODO(kenton):  Support other string reps.
534          case FieldOptions::STRING:
535            MutableRaw<RepeatedPtrField<string> >(message, field)->Clear();
536            break;
537        }
538        break;
539      }
540
541      case FieldDescriptor::CPPTYPE_MESSAGE: {
542        // We don't know which subclass of RepeatedPtrFieldBase the type is,
543        // so we use RepeatedPtrFieldBase directly.
544        MutableRaw<RepeatedPtrFieldBase>(message, field)
545            ->Clear<GenericTypeHandler<Message> >();
546        break;
547      }
548    }
549  }
550}
551
552void GeneratedMessageReflection::RemoveLast(
553    Message* message,
554    const FieldDescriptor* field) const {
555  USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
556  USAGE_CHECK_REPEATED(RemoveLast);
557
558  if (field->is_extension()) {
559    MutableExtensionSet(message)->RemoveLast(field->number());
560  } else {
561    switch (field->cpp_type()) {
562#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
563      case FieldDescriptor::CPPTYPE_##UPPERCASE :                             \
564        MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast();  \
565        break
566
567      HANDLE_TYPE( INT32,  int32);
568      HANDLE_TYPE( INT64,  int64);
569      HANDLE_TYPE(UINT32, uint32);
570      HANDLE_TYPE(UINT64, uint64);
571      HANDLE_TYPE(DOUBLE, double);
572      HANDLE_TYPE( FLOAT,  float);
573      HANDLE_TYPE(  BOOL,   bool);
574      HANDLE_TYPE(  ENUM,    int);
575#undef HANDLE_TYPE
576
577      case FieldDescriptor::CPPTYPE_STRING:
578        switch (field->options().ctype()) {
579          default:  // TODO(kenton):  Support other string reps.
580          case FieldOptions::STRING:
581            MutableRaw<RepeatedPtrField<string> >(message, field)->RemoveLast();
582            break;
583        }
584        break;
585
586      case FieldDescriptor::CPPTYPE_MESSAGE:
587        MutableRaw<RepeatedPtrFieldBase>(message, field)
588            ->RemoveLast<GenericTypeHandler<Message> >();
589        break;
590    }
591  }
592}
593
594void GeneratedMessageReflection::SwapElements(
595    Message* message,
596    const FieldDescriptor* field,
597    int index1,
598    int index2) const {
599  USAGE_CHECK_MESSAGE_TYPE(Swap);
600  USAGE_CHECK_REPEATED(Swap);
601
602  if (field->is_extension()) {
603    MutableExtensionSet(message)->SwapElements(field->number(), index1, index2);
604  } else {
605    switch (field->cpp_type()) {
606#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
607      case FieldDescriptor::CPPTYPE_##UPPERCASE :                             \
608        MutableRaw<RepeatedField<LOWERCASE> >(message, field)                 \
609            ->SwapElements(index1, index2);                                   \
610        break
611
612      HANDLE_TYPE( INT32,  int32);
613      HANDLE_TYPE( INT64,  int64);
614      HANDLE_TYPE(UINT32, uint32);
615      HANDLE_TYPE(UINT64, uint64);
616      HANDLE_TYPE(DOUBLE, double);
617      HANDLE_TYPE( FLOAT,  float);
618      HANDLE_TYPE(  BOOL,   bool);
619      HANDLE_TYPE(  ENUM,    int);
620#undef HANDLE_TYPE
621
622      case FieldDescriptor::CPPTYPE_STRING:
623      case FieldDescriptor::CPPTYPE_MESSAGE:
624        MutableRaw<RepeatedPtrFieldBase>(message, field)
625            ->SwapElements(index1, index2);
626        break;
627    }
628  }
629}
630
631namespace {
632// Comparison functor for sorting FieldDescriptors by field number.
633struct FieldNumberSorter {
634  bool operator()(const FieldDescriptor* left,
635                  const FieldDescriptor* right) const {
636    return left->number() < right->number();
637  }
638};
639}  // namespace
640
641void GeneratedMessageReflection::ListFields(
642    const Message& message,
643    vector<const FieldDescriptor*>* output) const {
644  output->clear();
645
646  // Optimization:  The default instance never has any fields set.
647  if (&message == default_instance_) return;
648
649  for (int i = 0; i < descriptor_->field_count(); i++) {
650    const FieldDescriptor* field = descriptor_->field(i);
651    if (field->is_repeated()) {
652      if (FieldSize(message, field) > 0) {
653        output->push_back(field);
654      }
655    } else {
656      if (HasBit(message, field)) {
657        output->push_back(field);
658      }
659    }
660  }
661
662  if (extensions_offset_ != -1) {
663    GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
664                                          output);
665  }
666
667  // ListFields() must sort output by field number.
668  sort(output->begin(), output->end(), FieldNumberSorter());
669}
670
671// -------------------------------------------------------------------
672
673#undef DEFINE_PRIMITIVE_ACCESSORS
674#define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE)        \
675  PASSTYPE GeneratedMessageReflection::Get##TYPENAME(                        \
676      const Message& message, const FieldDescriptor* field) const {          \
677    USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE);                       \
678    if (field->is_extension()) {                                             \
679      return GetExtensionSet(message).Get##TYPENAME(                         \
680        field->number(), field->default_value_##PASSTYPE());                 \
681    } else {                                                                 \
682      return GetField<TYPE>(message, field);                                 \
683    }                                                                        \
684  }                                                                          \
685                                                                             \
686  void GeneratedMessageReflection::Set##TYPENAME(                            \
687      Message* message, const FieldDescriptor* field,                        \
688      PASSTYPE value) const {                                                \
689    USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE);                       \
690    if (field->is_extension()) {                                             \
691      return MutableExtensionSet(message)->Set##TYPENAME(                    \
692        field->number(), field->type(), value, field);                       \
693    } else {                                                                 \
694      SetField<TYPE>(message, field, value);                                 \
695    }                                                                        \
696  }                                                                          \
697                                                                             \
698  PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME(                \
699      const Message& message,                                                \
700      const FieldDescriptor* field, int index) const {                       \
701    USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE);               \
702    if (field->is_extension()) {                                             \
703      return GetExtensionSet(message).GetRepeated##TYPENAME(                 \
704        field->number(), index);                                             \
705    } else {                                                                 \
706      return GetRepeatedField<TYPE>(message, field, index);                  \
707    }                                                                        \
708  }                                                                          \
709                                                                             \
710  void GeneratedMessageReflection::SetRepeated##TYPENAME(                    \
711      Message* message, const FieldDescriptor* field,                        \
712      int index, PASSTYPE value) const {                                     \
713    USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE);               \
714    if (field->is_extension()) {                                             \
715      MutableExtensionSet(message)->SetRepeated##TYPENAME(                   \
716        field->number(), index, value);                                      \
717    } else {                                                                 \
718      SetRepeatedField<TYPE>(message, field, index, value);                  \
719    }                                                                        \
720  }                                                                          \
721                                                                             \
722  void GeneratedMessageReflection::Add##TYPENAME(                            \
723      Message* message, const FieldDescriptor* field,                        \
724      PASSTYPE value) const {                                                \
725    USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE);                       \
726    if (field->is_extension()) {                                             \
727      MutableExtensionSet(message)->Add##TYPENAME(                           \
728        field->number(), field->type(), field->options().packed(), value,    \
729        field);                                                              \
730    } else {                                                                 \
731      AddField<TYPE>(message, field, value);                                 \
732    }                                                                        \
733  }
734
735DEFINE_PRIMITIVE_ACCESSORS(Int32 , int32 , int32 , INT32 )
736DEFINE_PRIMITIVE_ACCESSORS(Int64 , int64 , int64 , INT64 )
737DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32)
738DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64)
739DEFINE_PRIMITIVE_ACCESSORS(Float , float , float , FLOAT )
740DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE)
741DEFINE_PRIMITIVE_ACCESSORS(Bool  , bool  , bool  , BOOL  )
742#undef DEFINE_PRIMITIVE_ACCESSORS
743
744// -------------------------------------------------------------------
745
746string GeneratedMessageReflection::GetString(
747    const Message& message, const FieldDescriptor* field) const {
748  USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
749  if (field->is_extension()) {
750    return GetExtensionSet(message).GetString(field->number(),
751                                              field->default_value_string());
752  } else {
753    switch (field->options().ctype()) {
754      default:  // TODO(kenton):  Support other string reps.
755      case FieldOptions::STRING:
756        return *GetField<const string*>(message, field);
757    }
758
759    GOOGLE_LOG(FATAL) << "Can't get here.";
760    return kEmptyString;  // Make compiler happy.
761  }
762}
763
764const string& GeneratedMessageReflection::GetStringReference(
765    const Message& message,
766    const FieldDescriptor* field, string* scratch) const {
767  USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
768  if (field->is_extension()) {
769    return GetExtensionSet(message).GetString(field->number(),
770                                              field->default_value_string());
771  } else {
772    switch (field->options().ctype()) {
773      default:  // TODO(kenton):  Support other string reps.
774      case FieldOptions::STRING:
775        return *GetField<const string*>(message, field);
776    }
777
778    GOOGLE_LOG(FATAL) << "Can't get here.";
779    return kEmptyString;  // Make compiler happy.
780  }
781}
782
783
784void GeneratedMessageReflection::SetString(
785    Message* message, const FieldDescriptor* field,
786    const string& value) const {
787  USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
788  if (field->is_extension()) {
789    return MutableExtensionSet(message)->SetString(field->number(),
790                                                   field->type(), value, field);
791  } else {
792    switch (field->options().ctype()) {
793      default:  // TODO(kenton):  Support other string reps.
794      case FieldOptions::STRING: {
795        string** ptr = MutableField<string*>(message, field);
796        if (*ptr == DefaultRaw<const string*>(field)) {
797          *ptr = new string(value);
798        } else {
799          (*ptr)->assign(value);
800        }
801        break;
802      }
803    }
804  }
805}
806
807
808string GeneratedMessageReflection::GetRepeatedString(
809    const Message& message, const FieldDescriptor* field, int index) const {
810  USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
811  if (field->is_extension()) {
812    return GetExtensionSet(message).GetRepeatedString(field->number(), index);
813  } else {
814    switch (field->options().ctype()) {
815      default:  // TODO(kenton):  Support other string reps.
816      case FieldOptions::STRING:
817        return GetRepeatedPtrField<string>(message, field, index);
818    }
819
820    GOOGLE_LOG(FATAL) << "Can't get here.";
821    return kEmptyString;  // Make compiler happy.
822  }
823}
824
825const string& GeneratedMessageReflection::GetRepeatedStringReference(
826    const Message& message, const FieldDescriptor* field,
827    int index, string* scratch) const {
828  USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
829  if (field->is_extension()) {
830    return GetExtensionSet(message).GetRepeatedString(field->number(), index);
831  } else {
832    switch (field->options().ctype()) {
833      default:  // TODO(kenton):  Support other string reps.
834      case FieldOptions::STRING:
835        return GetRepeatedPtrField<string>(message, field, index);
836    }
837
838    GOOGLE_LOG(FATAL) << "Can't get here.";
839    return kEmptyString;  // Make compiler happy.
840  }
841}
842
843
844void GeneratedMessageReflection::SetRepeatedString(
845    Message* message, const FieldDescriptor* field,
846    int index, const string& value) const {
847  USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
848  if (field->is_extension()) {
849    MutableExtensionSet(message)->SetRepeatedString(
850      field->number(), index, value);
851  } else {
852    switch (field->options().ctype()) {
853      default:  // TODO(kenton):  Support other string reps.
854      case FieldOptions::STRING:
855        *MutableRepeatedField<string>(message, field, index) = value;
856        break;
857    }
858  }
859}
860
861
862void GeneratedMessageReflection::AddString(
863    Message* message, const FieldDescriptor* field,
864    const string& value) const {
865  USAGE_CHECK_ALL(AddString, REPEATED, STRING);
866  if (field->is_extension()) {
867    MutableExtensionSet(message)->AddString(field->number(),
868                                            field->type(), value, field);
869  } else {
870    switch (field->options().ctype()) {
871      default:  // TODO(kenton):  Support other string reps.
872      case FieldOptions::STRING:
873        *AddField<string>(message, field) = value;
874        break;
875    }
876  }
877}
878
879
880// -------------------------------------------------------------------
881
882const EnumValueDescriptor* GeneratedMessageReflection::GetEnum(
883    const Message& message, const FieldDescriptor* field) const {
884  USAGE_CHECK_ALL(GetEnum, SINGULAR, ENUM);
885
886  int value;
887  if (field->is_extension()) {
888    value = GetExtensionSet(message).GetEnum(
889      field->number(), field->default_value_enum()->number());
890  } else {
891    value = GetField<int>(message, field);
892  }
893  const EnumValueDescriptor* result =
894    field->enum_type()->FindValueByNumber(value);
895  GOOGLE_CHECK(result != NULL);
896  return result;
897}
898
899void GeneratedMessageReflection::SetEnum(
900    Message* message, const FieldDescriptor* field,
901    const EnumValueDescriptor* value) const {
902  USAGE_CHECK_ALL(SetEnum, SINGULAR, ENUM);
903  USAGE_CHECK_ENUM_VALUE(SetEnum);
904
905  if (field->is_extension()) {
906    MutableExtensionSet(message)->SetEnum(field->number(), field->type(),
907                                          value->number(), field);
908  } else {
909    SetField<int>(message, field, value->number());
910  }
911}
912
913const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum(
914    const Message& message, const FieldDescriptor* field, int index) const {
915  USAGE_CHECK_ALL(GetRepeatedEnum, REPEATED, ENUM);
916
917  int value;
918  if (field->is_extension()) {
919    value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
920  } else {
921    value = GetRepeatedField<int>(message, field, index);
922  }
923  const EnumValueDescriptor* result =
924    field->enum_type()->FindValueByNumber(value);
925  GOOGLE_CHECK(result != NULL);
926  return result;
927}
928
929void GeneratedMessageReflection::SetRepeatedEnum(
930    Message* message,
931    const FieldDescriptor* field, int index,
932    const EnumValueDescriptor* value) const {
933  USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
934  USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
935
936  if (field->is_extension()) {
937    MutableExtensionSet(message)->SetRepeatedEnum(
938      field->number(), index, value->number());
939  } else {
940    SetRepeatedField<int>(message, field, index, value->number());
941  }
942}
943
944void GeneratedMessageReflection::AddEnum(
945    Message* message, const FieldDescriptor* field,
946    const EnumValueDescriptor* value) const {
947  USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
948  USAGE_CHECK_ENUM_VALUE(AddEnum);
949
950  if (field->is_extension()) {
951    MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
952                                          field->options().packed(),
953                                          value->number(), field);
954  } else {
955    AddField<int>(message, field, value->number());
956  }
957}
958
959// -------------------------------------------------------------------
960
961const Message& GeneratedMessageReflection::GetMessage(
962    const Message& message, const FieldDescriptor* field,
963    MessageFactory* factory) const {
964  USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
965
966  if (field->is_extension()) {
967    return static_cast<const Message&>(
968        GetExtensionSet(message).GetMessage(
969          field->number(), field->message_type(),
970          factory == NULL ? message_factory_ : factory));
971  } else {
972    const Message* result = GetRaw<const Message*>(message, field);
973    if (result == NULL) {
974      result = DefaultRaw<const Message*>(field);
975    }
976    return *result;
977  }
978}
979
980Message* GeneratedMessageReflection::MutableMessage(
981    Message* message, const FieldDescriptor* field,
982    MessageFactory* factory) const {
983  USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
984
985  if (field->is_extension()) {
986    return static_cast<Message*>(
987        MutableExtensionSet(message)->MutableMessage(field,
988          factory == NULL ? message_factory_ : factory));
989  } else {
990    Message** result = MutableField<Message*>(message, field);
991    if (*result == NULL) {
992      const Message* default_message = DefaultRaw<const Message*>(field);
993      *result = default_message->New();
994    }
995    return *result;
996  }
997}
998
999const Message& GeneratedMessageReflection::GetRepeatedMessage(
1000    const Message& message, const FieldDescriptor* field, int index) const {
1001  USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
1002
1003  if (field->is_extension()) {
1004    return static_cast<const Message&>(
1005        GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
1006  } else {
1007    return GetRaw<RepeatedPtrFieldBase>(message, field)
1008        .Get<GenericTypeHandler<Message> >(index);
1009  }
1010}
1011
1012Message* GeneratedMessageReflection::MutableRepeatedMessage(
1013    Message* message, const FieldDescriptor* field, int index) const {
1014  USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
1015
1016  if (field->is_extension()) {
1017    return static_cast<Message*>(
1018        MutableExtensionSet(message)->MutableRepeatedMessage(
1019          field->number(), index));
1020  } else {
1021    return MutableRaw<RepeatedPtrFieldBase>(message, field)
1022        ->Mutable<GenericTypeHandler<Message> >(index);
1023  }
1024}
1025
1026Message* GeneratedMessageReflection::AddMessage(
1027    Message* message, const FieldDescriptor* field,
1028    MessageFactory* factory) const {
1029  USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
1030
1031  if (factory == NULL) factory = message_factory_;
1032
1033  if (field->is_extension()) {
1034    return static_cast<Message*>(
1035        MutableExtensionSet(message)->AddMessage(field, factory));
1036  } else {
1037    // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
1038    // know how to allocate one.
1039    RepeatedPtrFieldBase* repeated =
1040      MutableRaw<RepeatedPtrFieldBase>(message, field);
1041    Message* result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
1042    if (result == NULL) {
1043      // We must allocate a new object.
1044      const Message* prototype;
1045      if (repeated->size() == 0) {
1046        prototype = factory->GetPrototype(field->message_type());
1047      } else {
1048        prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
1049      }
1050      result = prototype->New();
1051      repeated->AddAllocated<GenericTypeHandler<Message> >(result);
1052    }
1053    return result;
1054  }
1055}
1056
1057// -------------------------------------------------------------------
1058
1059const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
1060    const string& name) const {
1061  if (extensions_offset_ == -1) return NULL;
1062
1063  const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
1064  if (result != NULL && result->containing_type() == descriptor_) {
1065    return result;
1066  }
1067
1068  if (descriptor_->options().message_set_wire_format()) {
1069    // MessageSet extensions may be identified by type name.
1070    const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name);
1071    if (type != NULL) {
1072      // Look for a matching extension in the foreign type's scope.
1073      for (int i = 0; i < type->extension_count(); i++) {
1074        const FieldDescriptor* extension = type->extension(i);
1075        if (extension->containing_type() == descriptor_ &&
1076            extension->type() == FieldDescriptor::TYPE_MESSAGE &&
1077            extension->is_optional() &&
1078            extension->message_type() == type) {
1079          // Found it.
1080          return extension;
1081        }
1082      }
1083    }
1084  }
1085
1086  return NULL;
1087}
1088
1089const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
1090    int number) const {
1091  if (extensions_offset_ == -1) return NULL;
1092  return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
1093}
1094
1095// ===================================================================
1096// Some private helpers.
1097
1098// These simple template accessors obtain pointers (or references) to
1099// the given field.
1100template <typename Type>
1101inline const Type& GeneratedMessageReflection::GetRaw(
1102    const Message& message, const FieldDescriptor* field) const {
1103  const void* ptr = reinterpret_cast<const uint8*>(&message) +
1104                    offsets_[field->index()];
1105  return *reinterpret_cast<const Type*>(ptr);
1106}
1107
1108template <typename Type>
1109inline Type* GeneratedMessageReflection::MutableRaw(
1110    Message* message, const FieldDescriptor* field) const {
1111  void* ptr = reinterpret_cast<uint8*>(message) + offsets_[field->index()];
1112  return reinterpret_cast<Type*>(ptr);
1113}
1114
1115template <typename Type>
1116inline const Type& GeneratedMessageReflection::DefaultRaw(
1117    const FieldDescriptor* field) const {
1118  const void* ptr = reinterpret_cast<const uint8*>(default_instance_) +
1119                    offsets_[field->index()];
1120  return *reinterpret_cast<const Type*>(ptr);
1121}
1122
1123inline const uint32* GeneratedMessageReflection::GetHasBits(
1124    const Message& message) const {
1125  const void* ptr = reinterpret_cast<const uint8*>(&message) + has_bits_offset_;
1126  return reinterpret_cast<const uint32*>(ptr);
1127}
1128inline uint32* GeneratedMessageReflection::MutableHasBits(
1129    Message* message) const {
1130  void* ptr = reinterpret_cast<uint8*>(message) + has_bits_offset_;
1131  return reinterpret_cast<uint32*>(ptr);
1132}
1133
1134inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet(
1135    const Message& message) const {
1136  GOOGLE_DCHECK_NE(extensions_offset_, -1);
1137  const void* ptr = reinterpret_cast<const uint8*>(&message) +
1138                    extensions_offset_;
1139  return *reinterpret_cast<const ExtensionSet*>(ptr);
1140}
1141inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet(
1142    Message* message) const {
1143  GOOGLE_DCHECK_NE(extensions_offset_, -1);
1144  void* ptr = reinterpret_cast<uint8*>(message) + extensions_offset_;
1145  return reinterpret_cast<ExtensionSet*>(ptr);
1146}
1147
1148// Simple accessors for manipulating has_bits_.
1149inline bool GeneratedMessageReflection::HasBit(
1150    const Message& message, const FieldDescriptor* field) const {
1151  return GetHasBits(message)[field->index() / 32] &
1152    (1 << (field->index() % 32));
1153}
1154
1155inline void GeneratedMessageReflection::SetBit(
1156    Message* message, const FieldDescriptor* field) const {
1157  MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32));
1158}
1159
1160inline void GeneratedMessageReflection::ClearBit(
1161    Message* message, const FieldDescriptor* field) const {
1162  MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32));
1163}
1164
1165// Template implementations of basic accessors.  Inline because each
1166// template instance is only called from one location.  These are
1167// used for all types except messages.
1168template <typename Type>
1169inline const Type& GeneratedMessageReflection::GetField(
1170    const Message& message, const FieldDescriptor* field) const {
1171  return GetRaw<Type>(message, field);
1172}
1173
1174template <typename Type>
1175inline void GeneratedMessageReflection::SetField(
1176    Message* message, const FieldDescriptor* field, const Type& value) const {
1177  *MutableRaw<Type>(message, field) = value;
1178  SetBit(message, field);
1179}
1180
1181template <typename Type>
1182inline Type* GeneratedMessageReflection::MutableField(
1183    Message* message, const FieldDescriptor* field) const {
1184  SetBit(message, field);
1185  return MutableRaw<Type>(message, field);
1186}
1187
1188template <typename Type>
1189inline const Type& GeneratedMessageReflection::GetRepeatedField(
1190    const Message& message, const FieldDescriptor* field, int index) const {
1191  return GetRaw<RepeatedField<Type> >(message, field).Get(index);
1192}
1193
1194template <typename Type>
1195inline const Type& GeneratedMessageReflection::GetRepeatedPtrField(
1196    const Message& message, const FieldDescriptor* field, int index) const {
1197  return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
1198}
1199
1200template <typename Type>
1201inline void GeneratedMessageReflection::SetRepeatedField(
1202    Message* message, const FieldDescriptor* field,
1203    int index, Type value) const {
1204  MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
1205}
1206
1207template <typename Type>
1208inline Type* GeneratedMessageReflection::MutableRepeatedField(
1209    Message* message, const FieldDescriptor* field, int index) const {
1210  RepeatedPtrField<Type>* repeated =
1211    MutableRaw<RepeatedPtrField<Type> >(message, field);
1212  return repeated->Mutable(index);
1213}
1214
1215template <typename Type>
1216inline void GeneratedMessageReflection::AddField(
1217    Message* message, const FieldDescriptor* field, const Type& value) const {
1218  MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
1219}
1220
1221template <typename Type>
1222inline Type* GeneratedMessageReflection::AddField(
1223    Message* message, const FieldDescriptor* field) const {
1224  RepeatedPtrField<Type>* repeated =
1225    MutableRaw<RepeatedPtrField<Type> >(message, field);
1226  return repeated->Add();
1227}
1228
1229}  // namespace internal
1230}  // namespace protobuf
1231}  // namespace google
1232