• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
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 <set>
37 
38 #include <google/protobuf/stubs/logging.h>
39 #include <google/protobuf/stubs/common.h>
40 #include <google/protobuf/descriptor.pb.h>
41 #include <google/protobuf/descriptor.h>
42 #include <google/protobuf/extension_set.h>
43 #include <google/protobuf/generated_message_reflection.h>
44 #include <google/protobuf/generated_message_util.h>
45 #include <google/protobuf/inlined_string_field.h>
46 #include <google/protobuf/map_field.h>
47 #include <google/protobuf/map_field_inl.h>
48 #include <google/protobuf/stubs/mutex.h>
49 #include <google/protobuf/repeated_field.h>
50 #include <google/protobuf/wire_format.h>
51 
52 
53 #include <google/protobuf/port_def.inc>
54 
55 #define GOOGLE_PROTOBUF_HAS_ONEOF
56 
57 using google::protobuf::internal::ArenaStringPtr;
58 using google::protobuf::internal::DescriptorTable;
59 using google::protobuf::internal::ExtensionSet;
60 using google::protobuf::internal::GenericTypeHandler;
61 using google::protobuf::internal::GetEmptyString;
62 using google::protobuf::internal::InlinedStringField;
63 using google::protobuf::internal::InternalMetadataWithArena;
64 using google::protobuf::internal::LazyField;
65 using google::protobuf::internal::MapFieldBase;
66 using google::protobuf::internal::MigrationSchema;
67 using google::protobuf::internal::OnShutdownDelete;
68 using google::protobuf::internal::ReflectionSchema;
69 using google::protobuf::internal::RepeatedPtrFieldBase;
70 using google::protobuf::internal::StringSpaceUsedExcludingSelfLong;
71 using google::protobuf::internal::WrappedMutex;
72 
73 namespace google {
74 namespace protobuf {
75 
76 namespace {
IsMapFieldInApi(const FieldDescriptor * field)77 bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); }
78 }  // anonymous namespace
79 
80 namespace internal {
81 
ParseNamedEnum(const EnumDescriptor * descriptor,const std::string & name,int * value)82 bool ParseNamedEnum(const EnumDescriptor* descriptor, const std::string& name,
83                     int* value) {
84   const EnumValueDescriptor* d = descriptor->FindValueByName(name);
85   if (d == nullptr) return false;
86   *value = d->number();
87   return true;
88 }
89 
NameOfEnum(const EnumDescriptor * descriptor,int value)90 const std::string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
91   const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
92   return (d == nullptr ? GetEmptyString() : d->name());
93 }
94 
95 }  // namespace internal
96 
97 // ===================================================================
98 // Helpers for reporting usage errors (e.g. trying to use GetInt32() on
99 // a string field).
100 
101 namespace {
102 
103 template <class To>
GetPointerAtOffset(Message * message,uint32 offset)104 To* GetPointerAtOffset(Message* message, uint32 offset) {
105   return reinterpret_cast<To*>(reinterpret_cast<char*>(message) + offset);
106 }
107 
108 template <class To>
GetConstPointerAtOffset(const Message * message,uint32 offset)109 const To* GetConstPointerAtOffset(const Message* message, uint32 offset) {
110   return reinterpret_cast<const To*>(reinterpret_cast<const char*>(message) +
111                                      offset);
112 }
113 
114 template <class To>
GetConstRefAtOffset(const Message & message,uint32 offset)115 const To& GetConstRefAtOffset(const Message& message, uint32 offset) {
116   return *GetConstPointerAtOffset<To>(&message, offset);
117 }
118 
ReportReflectionUsageError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,const char * description)119 void ReportReflectionUsageError(const Descriptor* descriptor,
120                                 const FieldDescriptor* field,
121                                 const char* method, const char* description) {
122   GOOGLE_LOG(FATAL) << "Protocol Buffer reflection usage error:\n"
123                 "  Method      : google::protobuf::Reflection::"
124              << method
125              << "\n"
126                 "  Message type: "
127              << descriptor->full_name()
128              << "\n"
129                 "  Field       : "
130              << field->full_name()
131              << "\n"
132                 "  Problem     : "
133              << description;
134 }
135 
136 const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = {
137     "INVALID_CPPTYPE", "CPPTYPE_INT32",  "CPPTYPE_INT64",  "CPPTYPE_UINT32",
138     "CPPTYPE_UINT64",  "CPPTYPE_DOUBLE", "CPPTYPE_FLOAT",  "CPPTYPE_BOOL",
139     "CPPTYPE_ENUM",    "CPPTYPE_STRING", "CPPTYPE_MESSAGE"};
140 
ReportReflectionUsageTypeError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,FieldDescriptor::CppType expected_type)141 static void ReportReflectionUsageTypeError(
142     const Descriptor* descriptor, const FieldDescriptor* field,
143     const char* method, FieldDescriptor::CppType expected_type) {
144   GOOGLE_LOG(FATAL)
145       << "Protocol Buffer reflection usage error:\n"
146          "  Method      : google::protobuf::Reflection::"
147       << method
148       << "\n"
149          "  Message type: "
150       << descriptor->full_name()
151       << "\n"
152          "  Field       : "
153       << field->full_name()
154       << "\n"
155          "  Problem     : Field is not the right type for this message:\n"
156          "    Expected  : "
157       << cpptype_names_[expected_type]
158       << "\n"
159          "    Field type: "
160       << cpptype_names_[field->cpp_type()];
161 }
162 
ReportReflectionUsageEnumTypeError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,const EnumValueDescriptor * value)163 static void ReportReflectionUsageEnumTypeError(
164     const Descriptor* descriptor, const FieldDescriptor* field,
165     const char* method, const EnumValueDescriptor* value) {
166   GOOGLE_LOG(FATAL) << "Protocol Buffer reflection usage error:\n"
167                 "  Method      : google::protobuf::Reflection::"
168              << method
169              << "\n"
170                 "  Message type: "
171              << descriptor->full_name()
172              << "\n"
173                 "  Field       : "
174              << field->full_name()
175              << "\n"
176                 "  Problem     : Enum value did not match field type:\n"
177                 "    Expected  : "
178              << field->enum_type()->full_name()
179              << "\n"
180                 "    Actual    : "
181              << value->full_name();
182 }
183 
184 #define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \
185   if (!(CONDITION))                                       \
186   ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION)
187 #define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \
188   USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION)
189 #define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \
190   USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION)
191 
192 #define USAGE_CHECK_TYPE(METHOD, CPPTYPE)                      \
193   if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \
194   ReportReflectionUsageTypeError(descriptor_, field, #METHOD,  \
195                                  FieldDescriptor::CPPTYPE_##CPPTYPE)
196 
197 #define USAGE_CHECK_ENUM_VALUE(METHOD)     \
198   if (value->type() != field->enum_type()) \
199   ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value)
200 
201 #define USAGE_CHECK_MESSAGE_TYPE(METHOD)                        \
202   USAGE_CHECK_EQ(field->containing_type(), descriptor_, METHOD, \
203                  "Field does not match message type.");
204 #define USAGE_CHECK_SINGULAR(METHOD)                                      \
205   USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
206                  "Field is repeated; the method requires a singular field.")
207 #define USAGE_CHECK_REPEATED(METHOD)                                      \
208   USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
209                  "Field is singular; the method requires a repeated field.")
210 
211 #define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \
212   USAGE_CHECK_MESSAGE_TYPE(METHOD);             \
213   USAGE_CHECK_##LABEL(METHOD);                  \
214   USAGE_CHECK_TYPE(METHOD, CPPTYPE)
215 
216 }  // namespace
217 
218 // ===================================================================
219 
Reflection(const Descriptor * descriptor,const internal::ReflectionSchema & schema,const DescriptorPool * pool,MessageFactory * factory)220 Reflection::Reflection(const Descriptor* descriptor,
221                        const internal::ReflectionSchema& schema,
222                        const DescriptorPool* pool, MessageFactory* factory)
223     : descriptor_(descriptor),
224       schema_(schema),
225       descriptor_pool_(
226           (pool == nullptr) ? DescriptorPool::internal_generated_pool() : pool),
227       message_factory_(factory),
228       last_non_weak_field_index_(-1) {
229   last_non_weak_field_index_ = descriptor_->field_count() - 1;
230 }
231 
GetUnknownFields(const Message & message) const232 const UnknownFieldSet& Reflection::GetUnknownFields(
233     const Message& message) const {
234   return GetInternalMetadataWithArena(message).unknown_fields();
235 }
236 
MutableUnknownFields(Message * message) const237 UnknownFieldSet* Reflection::MutableUnknownFields(Message* message) const {
238   return MutableInternalMetadataWithArena(message)->mutable_unknown_fields();
239 }
240 
SpaceUsedLong(const Message & message) const241 size_t Reflection::SpaceUsedLong(const Message& message) const {
242   // object_size_ already includes the in-memory representation of each field
243   // in the message, so we only need to account for additional memory used by
244   // the fields.
245   size_t total_size = schema_.GetObjectSize();
246 
247   total_size += GetUnknownFields(message).SpaceUsedExcludingSelfLong();
248 
249   if (schema_.HasExtensionSet()) {
250     total_size += GetExtensionSet(message).SpaceUsedExcludingSelfLong();
251   }
252   for (int i = 0; i <= last_non_weak_field_index_; i++) {
253     const FieldDescriptor* field = descriptor_->field(i);
254     if (field->is_repeated()) {
255       switch (field->cpp_type()) {
256 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                           \
257   case FieldDescriptor::CPPTYPE_##UPPERCASE:                        \
258     total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \
259                       .SpaceUsedExcludingSelfLong();                \
260     break
261 
262         HANDLE_TYPE(INT32, int32);
263         HANDLE_TYPE(INT64, int64);
264         HANDLE_TYPE(UINT32, uint32);
265         HANDLE_TYPE(UINT64, uint64);
266         HANDLE_TYPE(DOUBLE, double);
267         HANDLE_TYPE(FLOAT, float);
268         HANDLE_TYPE(BOOL, bool);
269         HANDLE_TYPE(ENUM, int);
270 #undef HANDLE_TYPE
271 
272         case FieldDescriptor::CPPTYPE_STRING:
273           switch (field->options().ctype()) {
274             default:  // TODO(kenton):  Support other string reps.
275             case FieldOptions::STRING:
276               total_size +=
277                   GetRaw<RepeatedPtrField<std::string> >(message, field)
278                       .SpaceUsedExcludingSelfLong();
279               break;
280           }
281           break;
282 
283         case FieldDescriptor::CPPTYPE_MESSAGE:
284           if (IsMapFieldInApi(field)) {
285             total_size += GetRaw<internal::MapFieldBase>(message, field)
286                               .SpaceUsedExcludingSelfLong();
287           } else {
288             // We don't know which subclass of RepeatedPtrFieldBase the type is,
289             // so we use RepeatedPtrFieldBase directly.
290             total_size +=
291                 GetRaw<RepeatedPtrFieldBase>(message, field)
292                     .SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >();
293           }
294 
295           break;
296       }
297     } else {
298       if (field->containing_oneof() && !HasOneofField(message, field)) {
299         continue;
300       }
301       switch (field->cpp_type()) {
302         case FieldDescriptor::CPPTYPE_INT32:
303         case FieldDescriptor::CPPTYPE_INT64:
304         case FieldDescriptor::CPPTYPE_UINT32:
305         case FieldDescriptor::CPPTYPE_UINT64:
306         case FieldDescriptor::CPPTYPE_DOUBLE:
307         case FieldDescriptor::CPPTYPE_FLOAT:
308         case FieldDescriptor::CPPTYPE_BOOL:
309         case FieldDescriptor::CPPTYPE_ENUM:
310           // Field is inline, so we've already counted it.
311           break;
312 
313         case FieldDescriptor::CPPTYPE_STRING: {
314           switch (field->options().ctype()) {
315             default:  // TODO(kenton):  Support other string reps.
316             case FieldOptions::STRING: {
317               if (IsInlined(field)) {
318                 const std::string* ptr =
319                     &GetField<InlinedStringField>(message, field).GetNoArena();
320                 total_size += StringSpaceUsedExcludingSelfLong(*ptr);
321                 break;
322               }
323 
324               // Initially, the string points to the default value stored
325               // in the prototype. Only count the string if it has been
326               // changed from the default value.
327               const std::string* default_ptr =
328                   &DefaultRaw<ArenaStringPtr>(field).Get();
329               const std::string* ptr =
330                   &GetField<ArenaStringPtr>(message, field).Get();
331 
332               if (ptr != default_ptr) {
333                 // string fields are represented by just a pointer, so also
334                 // include sizeof(string) as well.
335                 total_size +=
336                     sizeof(*ptr) + StringSpaceUsedExcludingSelfLong(*ptr);
337               }
338               break;
339             }
340           }
341           break;
342         }
343 
344         case FieldDescriptor::CPPTYPE_MESSAGE:
345           if (schema_.IsDefaultInstance(message)) {
346             // For singular fields, the prototype just stores a pointer to the
347             // external type's prototype, so there is no extra memory usage.
348           } else {
349             const Message* sub_message = GetRaw<const Message*>(message, field);
350             if (sub_message != nullptr) {
351               total_size += sub_message->SpaceUsedLong();
352             }
353           }
354           break;
355       }
356     }
357   }
358   return total_size;
359 }
360 
SwapField(Message * message1,Message * message2,const FieldDescriptor * field) const361 void Reflection::SwapField(Message* message1, Message* message2,
362                            const FieldDescriptor* field) const {
363   if (field->is_repeated()) {
364     switch (field->cpp_type()) {
365 #define SWAP_ARRAYS(CPPTYPE, TYPE)                                 \
366   case FieldDescriptor::CPPTYPE_##CPPTYPE:                         \
367     MutableRaw<RepeatedField<TYPE> >(message1, field)              \
368         ->Swap(MutableRaw<RepeatedField<TYPE> >(message2, field)); \
369     break;
370 
371       SWAP_ARRAYS(INT32, int32);
372       SWAP_ARRAYS(INT64, int64);
373       SWAP_ARRAYS(UINT32, uint32);
374       SWAP_ARRAYS(UINT64, uint64);
375       SWAP_ARRAYS(FLOAT, float);
376       SWAP_ARRAYS(DOUBLE, double);
377       SWAP_ARRAYS(BOOL, bool);
378       SWAP_ARRAYS(ENUM, int);
379 #undef SWAP_ARRAYS
380 
381       case FieldDescriptor::CPPTYPE_STRING:
382         switch (field->options().ctype()) {
383           default:  // TODO(kenton):  Support other string reps.
384           case FieldOptions::STRING:
385             MutableRaw<RepeatedPtrFieldBase>(message1, field)
386                 ->Swap<GenericTypeHandler<std::string> >(
387                     MutableRaw<RepeatedPtrFieldBase>(message2, field));
388             break;
389         }
390         break;
391       case FieldDescriptor::CPPTYPE_MESSAGE:
392         if (IsMapFieldInApi(field)) {
393           MutableRaw<MapFieldBase>(message1, field)
394               ->Swap(MutableRaw<MapFieldBase>(message2, field));
395         } else {
396           MutableRaw<RepeatedPtrFieldBase>(message1, field)
397               ->Swap<GenericTypeHandler<Message> >(
398                   MutableRaw<RepeatedPtrFieldBase>(message2, field));
399         }
400         break;
401 
402       default:
403         GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
404     }
405   } else {
406     switch (field->cpp_type()) {
407 #define SWAP_VALUES(CPPTYPE, TYPE)                 \
408   case FieldDescriptor::CPPTYPE_##CPPTYPE:         \
409     std::swap(*MutableRaw<TYPE>(message1, field),  \
410               *MutableRaw<TYPE>(message2, field)); \
411     break;
412 
413       SWAP_VALUES(INT32, int32);
414       SWAP_VALUES(INT64, int64);
415       SWAP_VALUES(UINT32, uint32);
416       SWAP_VALUES(UINT64, uint64);
417       SWAP_VALUES(FLOAT, float);
418       SWAP_VALUES(DOUBLE, double);
419       SWAP_VALUES(BOOL, bool);
420       SWAP_VALUES(ENUM, int);
421 #undef SWAP_VALUES
422       case FieldDescriptor::CPPTYPE_MESSAGE:
423         if (GetArena(message1) == GetArena(message2)) {
424           std::swap(*MutableRaw<Message*>(message1, field),
425                     *MutableRaw<Message*>(message2, field));
426         } else {
427           Message** sub_msg1 = MutableRaw<Message*>(message1, field);
428           Message** sub_msg2 = MutableRaw<Message*>(message2, field);
429           if (*sub_msg1 == nullptr && *sub_msg2 == nullptr) break;
430           if (*sub_msg1 && *sub_msg2) {
431             (*sub_msg1)->GetReflection()->Swap(*sub_msg1, *sub_msg2);
432             break;
433           }
434           if (*sub_msg1 == nullptr) {
435             *sub_msg1 = (*sub_msg2)->New(message1->GetArena());
436             (*sub_msg1)->CopyFrom(**sub_msg2);
437             ClearField(message2, field);
438           } else {
439             *sub_msg2 = (*sub_msg1)->New(message2->GetArena());
440             (*sub_msg2)->CopyFrom(**sub_msg1);
441             ClearField(message1, field);
442           }
443         }
444         break;
445 
446       case FieldDescriptor::CPPTYPE_STRING:
447         switch (field->options().ctype()) {
448           default:  // TODO(kenton):  Support other string reps.
449           case FieldOptions::STRING: {
450             Arena* arena1 = GetArena(message1);
451             Arena* arena2 = GetArena(message2);
452 
453             if (IsInlined(field)) {
454               InlinedStringField* string1 =
455                   MutableRaw<InlinedStringField>(message1, field);
456               InlinedStringField* string2 =
457                   MutableRaw<InlinedStringField>(message2, field);
458               string1->Swap(string2);
459               break;
460             }
461 
462             ArenaStringPtr* string1 =
463                 MutableRaw<ArenaStringPtr>(message1, field);
464             ArenaStringPtr* string2 =
465                 MutableRaw<ArenaStringPtr>(message2, field);
466             const std::string* default_ptr =
467                 &DefaultRaw<ArenaStringPtr>(field).Get();
468             if (arena1 == arena2) {
469               string1->Swap(string2, default_ptr, arena1);
470             } else {
471               const std::string temp = string1->Get();
472               string1->Set(default_ptr, string2->Get(), arena1);
473               string2->Set(default_ptr, temp, arena2);
474             }
475           } break;
476         }
477         break;
478 
479       default:
480         GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
481     }
482   }
483 }
484 
SwapOneofField(Message * message1,Message * message2,const OneofDescriptor * oneof_descriptor) const485 void Reflection::SwapOneofField(Message* message1, Message* message2,
486                                 const OneofDescriptor* oneof_descriptor) const {
487   uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor);
488   uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor);
489 
490   int32 temp_int32;
491   int64 temp_int64;
492   uint32 temp_uint32;
493   uint64 temp_uint64;
494   float temp_float;
495   double temp_double;
496   bool temp_bool;
497   int temp_int;
498   Message* temp_message = nullptr;
499   std::string temp_string;
500 
501   // Stores message1's oneof field to a temp variable.
502   const FieldDescriptor* field1 = nullptr;
503   if (oneof_case1 > 0) {
504     field1 = descriptor_->FindFieldByNumber(oneof_case1);
505     // oneof_descriptor->field(oneof_case1);
506     switch (field1->cpp_type()) {
507 #define GET_TEMP_VALUE(CPPTYPE, TYPE)                \
508   case FieldDescriptor::CPPTYPE_##CPPTYPE:           \
509     temp_##TYPE = GetField<TYPE>(*message1, field1); \
510     break;
511 
512       GET_TEMP_VALUE(INT32, int32);
513       GET_TEMP_VALUE(INT64, int64);
514       GET_TEMP_VALUE(UINT32, uint32);
515       GET_TEMP_VALUE(UINT64, uint64);
516       GET_TEMP_VALUE(FLOAT, float);
517       GET_TEMP_VALUE(DOUBLE, double);
518       GET_TEMP_VALUE(BOOL, bool);
519       GET_TEMP_VALUE(ENUM, int);
520 #undef GET_TEMP_VALUE
521       case FieldDescriptor::CPPTYPE_MESSAGE:
522         temp_message = ReleaseMessage(message1, field1);
523         break;
524 
525       case FieldDescriptor::CPPTYPE_STRING:
526         temp_string = GetString(*message1, field1);
527         break;
528 
529       default:
530         GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
531     }
532   }
533 
534   // Sets message1's oneof field from the message2's oneof field.
535   if (oneof_case2 > 0) {
536     const FieldDescriptor* field2 = descriptor_->FindFieldByNumber(oneof_case2);
537     switch (field2->cpp_type()) {
538 #define SET_ONEOF_VALUE1(CPPTYPE, TYPE)                                  \
539   case FieldDescriptor::CPPTYPE_##CPPTYPE:                               \
540     SetField<TYPE>(message1, field2, GetField<TYPE>(*message2, field2)); \
541     break;
542 
543       SET_ONEOF_VALUE1(INT32, int32);
544       SET_ONEOF_VALUE1(INT64, int64);
545       SET_ONEOF_VALUE1(UINT32, uint32);
546       SET_ONEOF_VALUE1(UINT64, uint64);
547       SET_ONEOF_VALUE1(FLOAT, float);
548       SET_ONEOF_VALUE1(DOUBLE, double);
549       SET_ONEOF_VALUE1(BOOL, bool);
550       SET_ONEOF_VALUE1(ENUM, int);
551 #undef SET_ONEOF_VALUE1
552       case FieldDescriptor::CPPTYPE_MESSAGE:
553         SetAllocatedMessage(message1, ReleaseMessage(message2, field2), field2);
554         break;
555 
556       case FieldDescriptor::CPPTYPE_STRING:
557         SetString(message1, field2, GetString(*message2, field2));
558         break;
559 
560       default:
561         GOOGLE_LOG(FATAL) << "Unimplemented type: " << field2->cpp_type();
562     }
563   } else {
564     ClearOneof(message1, oneof_descriptor);
565   }
566 
567   // Sets message2's oneof field from the temp variable.
568   if (oneof_case1 > 0) {
569     switch (field1->cpp_type()) {
570 #define SET_ONEOF_VALUE2(CPPTYPE, TYPE)            \
571   case FieldDescriptor::CPPTYPE_##CPPTYPE:         \
572     SetField<TYPE>(message2, field1, temp_##TYPE); \
573     break;
574 
575       SET_ONEOF_VALUE2(INT32, int32);
576       SET_ONEOF_VALUE2(INT64, int64);
577       SET_ONEOF_VALUE2(UINT32, uint32);
578       SET_ONEOF_VALUE2(UINT64, uint64);
579       SET_ONEOF_VALUE2(FLOAT, float);
580       SET_ONEOF_VALUE2(DOUBLE, double);
581       SET_ONEOF_VALUE2(BOOL, bool);
582       SET_ONEOF_VALUE2(ENUM, int);
583 #undef SET_ONEOF_VALUE2
584       case FieldDescriptor::CPPTYPE_MESSAGE:
585         SetAllocatedMessage(message2, temp_message, field1);
586         break;
587 
588       case FieldDescriptor::CPPTYPE_STRING:
589         SetString(message2, field1, temp_string);
590         break;
591 
592       default:
593         GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
594     }
595   } else {
596     ClearOneof(message2, oneof_descriptor);
597   }
598 }
599 
Swap(Message * message1,Message * message2) const600 void Reflection::Swap(Message* message1, Message* message2) const {
601   if (message1 == message2) return;
602 
603   // TODO(kenton):  Other Reflection methods should probably check this too.
604   GOOGLE_CHECK_EQ(message1->GetReflection(), this)
605       << "First argument to Swap() (of type \""
606       << message1->GetDescriptor()->full_name()
607       << "\") is not compatible with this reflection object (which is for type "
608          "\""
609       << descriptor_->full_name()
610       << "\").  Note that the exact same class is required; not just the same "
611          "descriptor.";
612   GOOGLE_CHECK_EQ(message2->GetReflection(), this)
613       << "Second argument to Swap() (of type \""
614       << message2->GetDescriptor()->full_name()
615       << "\") is not compatible with this reflection object (which is for type "
616          "\""
617       << descriptor_->full_name()
618       << "\").  Note that the exact same class is required; not just the same "
619          "descriptor.";
620 
621   // Check that both messages are in the same arena (or both on the heap). We
622   // need to copy all data if not, due to ownership semantics.
623   if (GetArena(message1) != GetArena(message2)) {
624     // Slow copy path.
625     // Use our arena as temp space, if available.
626     Message* temp = message1->New(GetArena(message1));
627     temp->MergeFrom(*message2);
628     message2->CopyFrom(*message1);
629     Swap(message1, temp);
630     if (GetArena(message1) == nullptr) {
631       delete temp;
632     }
633     return;
634   }
635 
636   if (schema_.HasHasbits()) {
637     uint32* has_bits1 = MutableHasBits(message1);
638     uint32* has_bits2 = MutableHasBits(message2);
639 
640     int fields_with_has_bits = 0;
641     for (int i = 0; i < descriptor_->field_count(); i++) {
642       const FieldDescriptor* field = descriptor_->field(i);
643       if (field->is_repeated() || field->containing_oneof()) {
644         continue;
645       }
646       fields_with_has_bits++;
647     }
648 
649     int has_bits_size = (fields_with_has_bits + 31) / 32;
650 
651     for (int i = 0; i < has_bits_size; i++) {
652       std::swap(has_bits1[i], has_bits2[i]);
653     }
654   }
655 
656   for (int i = 0; i <= last_non_weak_field_index_; i++) {
657     const FieldDescriptor* field = descriptor_->field(i);
658     if (field->containing_oneof()) continue;
659     SwapField(message1, message2, field);
660   }
661   const int oneof_decl_count = descriptor_->oneof_decl_count();
662   for (int i = 0; i < oneof_decl_count; i++) {
663     SwapOneofField(message1, message2, descriptor_->oneof_decl(i));
664   }
665 
666   if (schema_.HasExtensionSet()) {
667     MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
668   }
669 
670   MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
671 }
672 
SwapFields(Message * message1,Message * message2,const std::vector<const FieldDescriptor * > & fields) const673 void Reflection::SwapFields(
674     Message* message1, Message* message2,
675     const std::vector<const FieldDescriptor*>& fields) const {
676   if (message1 == message2) return;
677 
678   // TODO(kenton):  Other Reflection methods should probably check this too.
679   GOOGLE_CHECK_EQ(message1->GetReflection(), this)
680       << "First argument to SwapFields() (of type \""
681       << message1->GetDescriptor()->full_name()
682       << "\") is not compatible with this reflection object (which is for type "
683          "\""
684       << descriptor_->full_name()
685       << "\").  Note that the exact same class is required; not just the same "
686          "descriptor.";
687   GOOGLE_CHECK_EQ(message2->GetReflection(), this)
688       << "Second argument to SwapFields() (of type \""
689       << message2->GetDescriptor()->full_name()
690       << "\") is not compatible with this reflection object (which is for type "
691          "\""
692       << descriptor_->full_name()
693       << "\").  Note that the exact same class is required; not just the same "
694          "descriptor.";
695 
696   std::set<int> swapped_oneof;
697 
698   const int fields_size = static_cast<int>(fields.size());
699   for (int i = 0; i < fields_size; i++) {
700     const FieldDescriptor* field = fields[i];
701     if (field->is_extension()) {
702       MutableExtensionSet(message1)->SwapExtension(
703           MutableExtensionSet(message2), field->number());
704     } else {
705       if (field->containing_oneof()) {
706         int oneof_index = field->containing_oneof()->index();
707         // Only swap the oneof field once.
708         if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
709           continue;
710         }
711         swapped_oneof.insert(oneof_index);
712         SwapOneofField(message1, message2, field->containing_oneof());
713       } else {
714         // Swap has bit for non-repeated fields.  We have already checked for
715         // oneof already.
716         if (!field->is_repeated()) {
717           SwapBit(message1, message2, field);
718         }
719         // Swap field.
720         SwapField(message1, message2, field);
721       }
722     }
723   }
724 }
725 
726 // -------------------------------------------------------------------
727 
HasField(const Message & message,const FieldDescriptor * field) const728 bool Reflection::HasField(const Message& message,
729                           const FieldDescriptor* field) const {
730   USAGE_CHECK_MESSAGE_TYPE(HasField);
731   USAGE_CHECK_SINGULAR(HasField);
732 
733   if (field->is_extension()) {
734     return GetExtensionSet(message).Has(field->number());
735   } else {
736     if (field->containing_oneof()) {
737       return HasOneofField(message, field);
738     } else {
739       return HasBit(message, field);
740     }
741   }
742 }
743 
FieldSize(const Message & message,const FieldDescriptor * field) const744 int Reflection::FieldSize(const Message& message,
745                           const FieldDescriptor* field) const {
746   USAGE_CHECK_MESSAGE_TYPE(FieldSize);
747   USAGE_CHECK_REPEATED(FieldSize);
748 
749   if (field->is_extension()) {
750     return GetExtensionSet(message).ExtensionSize(field->number());
751   } else {
752     switch (field->cpp_type()) {
753 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)    \
754   case FieldDescriptor::CPPTYPE_##UPPERCASE: \
755     return GetRaw<RepeatedField<LOWERCASE> >(message, field).size()
756 
757       HANDLE_TYPE(INT32, int32);
758       HANDLE_TYPE(INT64, int64);
759       HANDLE_TYPE(UINT32, uint32);
760       HANDLE_TYPE(UINT64, uint64);
761       HANDLE_TYPE(DOUBLE, double);
762       HANDLE_TYPE(FLOAT, float);
763       HANDLE_TYPE(BOOL, bool);
764       HANDLE_TYPE(ENUM, int);
765 #undef HANDLE_TYPE
766 
767       case FieldDescriptor::CPPTYPE_STRING:
768       case FieldDescriptor::CPPTYPE_MESSAGE:
769         if (IsMapFieldInApi(field)) {
770           const internal::MapFieldBase& map =
771               GetRaw<MapFieldBase>(message, field);
772           if (map.IsRepeatedFieldValid()) {
773             return map.GetRepeatedField().size();
774           } else {
775             // No need to materialize the repeated field if it is out of sync:
776             // its size will be the same as the map's size.
777             return map.size();
778           }
779         } else {
780           return GetRaw<RepeatedPtrFieldBase>(message, field).size();
781         }
782     }
783 
784     GOOGLE_LOG(FATAL) << "Can't get here.";
785     return 0;
786   }
787 }
788 
ClearField(Message * message,const FieldDescriptor * field) const789 void Reflection::ClearField(Message* message,
790                             const FieldDescriptor* field) const {
791   USAGE_CHECK_MESSAGE_TYPE(ClearField);
792 
793   if (field->is_extension()) {
794     MutableExtensionSet(message)->ClearExtension(field->number());
795   } else if (!field->is_repeated()) {
796     if (field->containing_oneof()) {
797       ClearOneofField(message, field);
798       return;
799     }
800     if (HasBit(*message, field)) {
801       ClearBit(message, field);
802 
803       // We need to set the field back to its default value.
804       switch (field->cpp_type()) {
805 #define CLEAR_TYPE(CPPTYPE, TYPE)                                      \
806   case FieldDescriptor::CPPTYPE_##CPPTYPE:                             \
807     *MutableRaw<TYPE>(message, field) = field->default_value_##TYPE(); \
808     break;
809 
810         CLEAR_TYPE(INT32, int32);
811         CLEAR_TYPE(INT64, int64);
812         CLEAR_TYPE(UINT32, uint32);
813         CLEAR_TYPE(UINT64, uint64);
814         CLEAR_TYPE(FLOAT, float);
815         CLEAR_TYPE(DOUBLE, double);
816         CLEAR_TYPE(BOOL, bool);
817 #undef CLEAR_TYPE
818 
819         case FieldDescriptor::CPPTYPE_ENUM:
820           *MutableRaw<int>(message, field) =
821               field->default_value_enum()->number();
822           break;
823 
824         case FieldDescriptor::CPPTYPE_STRING: {
825           switch (field->options().ctype()) {
826             default:  // TODO(kenton):  Support other string reps.
827             case FieldOptions::STRING: {
828               if (IsInlined(field)) {
829                 const std::string* default_ptr =
830                     &DefaultRaw<InlinedStringField>(field).GetNoArena();
831                 MutableRaw<InlinedStringField>(message, field)
832                     ->SetNoArena(default_ptr, *default_ptr);
833                 break;
834               }
835 
836               const std::string* default_ptr =
837                   &DefaultRaw<ArenaStringPtr>(field).Get();
838               MutableRaw<ArenaStringPtr>(message, field)
839                   ->SetAllocated(default_ptr, nullptr, GetArena(message));
840               break;
841             }
842           }
843           break;
844         }
845 
846         case FieldDescriptor::CPPTYPE_MESSAGE:
847           if (!schema_.HasHasbits()) {
848             // Proto3 does not have has-bits and we need to set a message field
849             // to nullptr in order to indicate its un-presence.
850             if (GetArena(message) == nullptr) {
851               delete *MutableRaw<Message*>(message, field);
852             }
853             *MutableRaw<Message*>(message, field) = nullptr;
854           } else {
855             (*MutableRaw<Message*>(message, field))->Clear();
856           }
857           break;
858       }
859     }
860   } else {
861     switch (field->cpp_type()) {
862 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                           \
863   case FieldDescriptor::CPPTYPE_##UPPERCASE:                        \
864     MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear(); \
865     break
866 
867       HANDLE_TYPE(INT32, int32);
868       HANDLE_TYPE(INT64, int64);
869       HANDLE_TYPE(UINT32, uint32);
870       HANDLE_TYPE(UINT64, uint64);
871       HANDLE_TYPE(DOUBLE, double);
872       HANDLE_TYPE(FLOAT, float);
873       HANDLE_TYPE(BOOL, bool);
874       HANDLE_TYPE(ENUM, int);
875 #undef HANDLE_TYPE
876 
877       case FieldDescriptor::CPPTYPE_STRING: {
878         switch (field->options().ctype()) {
879           default:  // TODO(kenton):  Support other string reps.
880           case FieldOptions::STRING:
881             MutableRaw<RepeatedPtrField<std::string> >(message, field)->Clear();
882             break;
883         }
884         break;
885       }
886 
887       case FieldDescriptor::CPPTYPE_MESSAGE: {
888         if (IsMapFieldInApi(field)) {
889           MutableRaw<MapFieldBase>(message, field)->Clear();
890         } else {
891           // We don't know which subclass of RepeatedPtrFieldBase the type is,
892           // so we use RepeatedPtrFieldBase directly.
893           MutableRaw<RepeatedPtrFieldBase>(message, field)
894               ->Clear<GenericTypeHandler<Message> >();
895         }
896         break;
897       }
898     }
899   }
900 }
901 
RemoveLast(Message * message,const FieldDescriptor * field) const902 void Reflection::RemoveLast(Message* message,
903                             const FieldDescriptor* field) const {
904   USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
905   USAGE_CHECK_REPEATED(RemoveLast);
906 
907   if (field->is_extension()) {
908     MutableExtensionSet(message)->RemoveLast(field->number());
909   } else {
910     switch (field->cpp_type()) {
911 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                \
912   case FieldDescriptor::CPPTYPE_##UPPERCASE:                             \
913     MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast(); \
914     break
915 
916       HANDLE_TYPE(INT32, int32);
917       HANDLE_TYPE(INT64, int64);
918       HANDLE_TYPE(UINT32, uint32);
919       HANDLE_TYPE(UINT64, uint64);
920       HANDLE_TYPE(DOUBLE, double);
921       HANDLE_TYPE(FLOAT, float);
922       HANDLE_TYPE(BOOL, bool);
923       HANDLE_TYPE(ENUM, int);
924 #undef HANDLE_TYPE
925 
926       case FieldDescriptor::CPPTYPE_STRING:
927         switch (field->options().ctype()) {
928           default:  // TODO(kenton):  Support other string reps.
929           case FieldOptions::STRING:
930             MutableRaw<RepeatedPtrField<std::string> >(message, field)
931                 ->RemoveLast();
932             break;
933         }
934         break;
935 
936       case FieldDescriptor::CPPTYPE_MESSAGE:
937         if (IsMapFieldInApi(field)) {
938           MutableRaw<MapFieldBase>(message, field)
939               ->MutableRepeatedField()
940               ->RemoveLast<GenericTypeHandler<Message> >();
941         } else {
942           MutableRaw<RepeatedPtrFieldBase>(message, field)
943               ->RemoveLast<GenericTypeHandler<Message> >();
944         }
945         break;
946     }
947   }
948 }
949 
ReleaseLast(Message * message,const FieldDescriptor * field) const950 Message* Reflection::ReleaseLast(Message* message,
951                                  const FieldDescriptor* field) const {
952   USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE);
953 
954   if (field->is_extension()) {
955     return static_cast<Message*>(
956         MutableExtensionSet(message)->ReleaseLast(field->number()));
957   } else {
958     if (IsMapFieldInApi(field)) {
959       return MutableRaw<MapFieldBase>(message, field)
960           ->MutableRepeatedField()
961           ->ReleaseLast<GenericTypeHandler<Message> >();
962     } else {
963       return MutableRaw<RepeatedPtrFieldBase>(message, field)
964           ->ReleaseLast<GenericTypeHandler<Message> >();
965     }
966   }
967 }
968 
SwapElements(Message * message,const FieldDescriptor * field,int index1,int index2) const969 void Reflection::SwapElements(Message* message, const FieldDescriptor* field,
970                               int index1, int index2) const {
971   USAGE_CHECK_MESSAGE_TYPE(Swap);
972   USAGE_CHECK_REPEATED(Swap);
973 
974   if (field->is_extension()) {
975     MutableExtensionSet(message)->SwapElements(field->number(), index1, index2);
976   } else {
977     switch (field->cpp_type()) {
978 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                 \
979   case FieldDescriptor::CPPTYPE_##UPPERCASE:              \
980     MutableRaw<RepeatedField<LOWERCASE> >(message, field) \
981         ->SwapElements(index1, index2);                   \
982     break
983 
984       HANDLE_TYPE(INT32, int32);
985       HANDLE_TYPE(INT64, int64);
986       HANDLE_TYPE(UINT32, uint32);
987       HANDLE_TYPE(UINT64, uint64);
988       HANDLE_TYPE(DOUBLE, double);
989       HANDLE_TYPE(FLOAT, float);
990       HANDLE_TYPE(BOOL, bool);
991       HANDLE_TYPE(ENUM, int);
992 #undef HANDLE_TYPE
993 
994       case FieldDescriptor::CPPTYPE_STRING:
995       case FieldDescriptor::CPPTYPE_MESSAGE:
996         if (IsMapFieldInApi(field)) {
997           MutableRaw<MapFieldBase>(message, field)
998               ->MutableRepeatedField()
999               ->SwapElements(index1, index2);
1000         } else {
1001           MutableRaw<RepeatedPtrFieldBase>(message, field)
1002               ->SwapElements(index1, index2);
1003         }
1004         break;
1005     }
1006   }
1007 }
1008 
1009 namespace {
1010 // Comparison functor for sorting FieldDescriptors by field number.
1011 struct FieldNumberSorter {
operator ()google::protobuf::__anonfa96d48c0311::FieldNumberSorter1012   bool operator()(const FieldDescriptor* left,
1013                   const FieldDescriptor* right) const {
1014     return left->number() < right->number();
1015   }
1016 };
1017 
IsIndexInHasBitSet(const uint32 * has_bit_set,uint32 has_bit_index)1018 bool IsIndexInHasBitSet(const uint32* has_bit_set, uint32 has_bit_index) {
1019   GOOGLE_DCHECK_NE(has_bit_index, ~0u);
1020   return ((has_bit_set[has_bit_index / 32] >> (has_bit_index % 32)) &
1021           static_cast<uint32>(1)) != 0;
1022 }
1023 
CreateUnknownEnumValues(const FileDescriptor * file)1024 bool CreateUnknownEnumValues(const FileDescriptor* file) {
1025   return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
1026 }
1027 }  // namespace
1028 
ListFields(const Message & message,std::vector<const FieldDescriptor * > * output) const1029 void Reflection::ListFields(const Message& message,
1030                             std::vector<const FieldDescriptor*>* output) const {
1031   output->clear();
1032 
1033   // Optimization:  The default instance never has any fields set.
1034   if (schema_.IsDefaultInstance(message)) return;
1035 
1036   // Optimization: Avoid calling GetHasBits() and HasOneofField() many times
1037   // within the field loop.  We allow this violation of ReflectionSchema
1038   // encapsulation because this function takes a noticable about of CPU
1039   // fleetwide and properly allowing this optimization through public interfaces
1040   // seems more trouble than it is worth.
1041   const uint32* const has_bits =
1042       schema_.HasHasbits() ? GetHasBits(message) : nullptr;
1043   const uint32* const has_bits_indices = schema_.has_bit_indices_;
1044   output->reserve(descriptor_->field_count());
1045   for (int i = 0; i <= last_non_weak_field_index_; i++) {
1046     const FieldDescriptor* field = descriptor_->field(i);
1047     if (field->is_repeated()) {
1048       if (FieldSize(message, field) > 0) {
1049         output->push_back(field);
1050       }
1051     } else {
1052       const OneofDescriptor* containing_oneof = field->containing_oneof();
1053       if (containing_oneof) {
1054         const uint32* const oneof_case_array = GetConstPointerAtOffset<uint32>(
1055             &message, schema_.oneof_case_offset_);
1056         // Equivalent to: HasOneofField(message, field)
1057         if (oneof_case_array[containing_oneof->index()] == field->number()) {
1058           output->push_back(field);
1059         }
1060       } else if (has_bits) {
1061         // Equivalent to: HasBit(message, field)
1062         if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) {
1063           output->push_back(field);
1064         }
1065       } else if (HasBit(message, field)) {  // Fall back on proto3-style HasBit.
1066         output->push_back(field);
1067       }
1068     }
1069   }
1070   if (schema_.HasExtensionSet()) {
1071     GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
1072                                           output);
1073   }
1074 
1075   // ListFields() must sort output by field number.
1076   std::sort(output->begin(), output->end(), FieldNumberSorter());
1077 }
1078 
1079 // -------------------------------------------------------------------
1080 
1081 #undef DEFINE_PRIMITIVE_ACCESSORS
1082 #define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE)          \
1083   PASSTYPE Reflection::Get##TYPENAME(const Message& message,                   \
1084                                      const FieldDescriptor* field) const {     \
1085     USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE);                         \
1086     if (field->is_extension()) {                                               \
1087       return GetExtensionSet(message).Get##TYPENAME(                           \
1088           field->number(), field->default_value_##PASSTYPE());                 \
1089     } else {                                                                   \
1090       return GetField<TYPE>(message, field);                                   \
1091     }                                                                          \
1092   }                                                                            \
1093                                                                                \
1094   void Reflection::Set##TYPENAME(                                              \
1095       Message* message, const FieldDescriptor* field, PASSTYPE value) const {  \
1096     USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE);                         \
1097     if (field->is_extension()) {                                               \
1098       return MutableExtensionSet(message)->Set##TYPENAME(                      \
1099           field->number(), field->type(), value, field);                       \
1100     } else {                                                                   \
1101       SetField<TYPE>(message, field, value);                                   \
1102     }                                                                          \
1103   }                                                                            \
1104                                                                                \
1105   PASSTYPE Reflection::GetRepeated##TYPENAME(                                  \
1106       const Message& message, const FieldDescriptor* field, int index) const { \
1107     USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE);                 \
1108     if (field->is_extension()) {                                               \
1109       return GetExtensionSet(message).GetRepeated##TYPENAME(field->number(),   \
1110                                                             index);            \
1111     } else {                                                                   \
1112       return GetRepeatedField<TYPE>(message, field, index);                    \
1113     }                                                                          \
1114   }                                                                            \
1115                                                                                \
1116   void Reflection::SetRepeated##TYPENAME(Message* message,                     \
1117                                          const FieldDescriptor* field,         \
1118                                          int index, PASSTYPE value) const {    \
1119     USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE);                 \
1120     if (field->is_extension()) {                                               \
1121       MutableExtensionSet(message)->SetRepeated##TYPENAME(field->number(),     \
1122                                                           index, value);       \
1123     } else {                                                                   \
1124       SetRepeatedField<TYPE>(message, field, index, value);                    \
1125     }                                                                          \
1126   }                                                                            \
1127                                                                                \
1128   void Reflection::Add##TYPENAME(                                              \
1129       Message* message, const FieldDescriptor* field, PASSTYPE value) const {  \
1130     USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE);                         \
1131     if (field->is_extension()) {                                               \
1132       MutableExtensionSet(message)->Add##TYPENAME(                             \
1133           field->number(), field->type(), field->options().packed(), value,    \
1134           field);                                                              \
1135     } else {                                                                   \
1136       AddField<TYPE>(message, field, value);                                   \
1137     }                                                                          \
1138   }
1139 
DEFINE_PRIMITIVE_ACCESSORS(Int32,int32,int32,INT32)1140 DEFINE_PRIMITIVE_ACCESSORS(Int32, int32, int32, INT32)
1141 DEFINE_PRIMITIVE_ACCESSORS(Int64, int64, int64, INT64)
1142 DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32)
1143 DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64)
1144 DEFINE_PRIMITIVE_ACCESSORS(Float, float, float, FLOAT)
1145 DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE)
1146 DEFINE_PRIMITIVE_ACCESSORS(Bool, bool, bool, BOOL)
1147 #undef DEFINE_PRIMITIVE_ACCESSORS
1148 
1149 // -------------------------------------------------------------------
1150 
1151 std::string Reflection::GetString(const Message& message,
1152                                   const FieldDescriptor* field) const {
1153   USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
1154   if (field->is_extension()) {
1155     return GetExtensionSet(message).GetString(field->number(),
1156                                               field->default_value_string());
1157   } else {
1158     switch (field->options().ctype()) {
1159       default:  // TODO(kenton):  Support other string reps.
1160       case FieldOptions::STRING: {
1161         if (IsInlined(field)) {
1162           return GetField<InlinedStringField>(message, field).GetNoArena();
1163         }
1164 
1165         return GetField<ArenaStringPtr>(message, field).Get();
1166       }
1167     }
1168   }
1169 }
1170 
GetStringReference(const Message & message,const FieldDescriptor * field,std::string * scratch) const1171 const std::string& Reflection::GetStringReference(const Message& message,
1172                                                   const FieldDescriptor* field,
1173                                                   std::string* scratch) const {
1174   USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
1175   if (field->is_extension()) {
1176     return GetExtensionSet(message).GetString(field->number(),
1177                                               field->default_value_string());
1178   } else {
1179     switch (field->options().ctype()) {
1180       default:  // TODO(kenton):  Support other string reps.
1181       case FieldOptions::STRING: {
1182         if (IsInlined(field)) {
1183           return GetField<InlinedStringField>(message, field).GetNoArena();
1184         }
1185 
1186         return GetField<ArenaStringPtr>(message, field).Get();
1187       }
1188     }
1189   }
1190 }
1191 
1192 
SetString(Message * message,const FieldDescriptor * field,const std::string & value) const1193 void Reflection::SetString(Message* message, const FieldDescriptor* field,
1194                            const std::string& value) const {
1195   USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
1196   if (field->is_extension()) {
1197     return MutableExtensionSet(message)->SetString(field->number(),
1198                                                    field->type(), value, field);
1199   } else {
1200     switch (field->options().ctype()) {
1201       default:  // TODO(kenton):  Support other string reps.
1202       case FieldOptions::STRING: {
1203         if (IsInlined(field)) {
1204           MutableField<InlinedStringField>(message, field)
1205               ->SetNoArena(nullptr, value);
1206           break;
1207         }
1208 
1209         const std::string* default_ptr =
1210             &DefaultRaw<ArenaStringPtr>(field).Get();
1211         if (field->containing_oneof() && !HasOneofField(*message, field)) {
1212           ClearOneof(message, field->containing_oneof());
1213           MutableField<ArenaStringPtr>(message, field)
1214               ->UnsafeSetDefault(default_ptr);
1215         }
1216         MutableField<ArenaStringPtr>(message, field)
1217             ->Mutable(default_ptr, GetArena(message))
1218             ->assign(value);
1219         break;
1220       }
1221     }
1222   }
1223 }
1224 
1225 
GetRepeatedString(const Message & message,const FieldDescriptor * field,int index) const1226 std::string Reflection::GetRepeatedString(const Message& message,
1227                                           const FieldDescriptor* field,
1228                                           int index) const {
1229   USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
1230   if (field->is_extension()) {
1231     return GetExtensionSet(message).GetRepeatedString(field->number(), index);
1232   } else {
1233     switch (field->options().ctype()) {
1234       default:  // TODO(kenton):  Support other string reps.
1235       case FieldOptions::STRING:
1236         return GetRepeatedPtrField<std::string>(message, field, index);
1237     }
1238   }
1239 }
1240 
GetRepeatedStringReference(const Message & message,const FieldDescriptor * field,int index,std::string * scratch) const1241 const std::string& Reflection::GetRepeatedStringReference(
1242     const Message& message, const FieldDescriptor* field, int index,
1243     std::string* scratch) const {
1244   USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
1245   if (field->is_extension()) {
1246     return GetExtensionSet(message).GetRepeatedString(field->number(), index);
1247   } else {
1248     switch (field->options().ctype()) {
1249       default:  // TODO(kenton):  Support other string reps.
1250       case FieldOptions::STRING:
1251         return GetRepeatedPtrField<std::string>(message, field, index);
1252     }
1253   }
1254 }
1255 
1256 
SetRepeatedString(Message * message,const FieldDescriptor * field,int index,const std::string & value) const1257 void Reflection::SetRepeatedString(Message* message,
1258                                    const FieldDescriptor* field, int index,
1259                                    const std::string& value) const {
1260   USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
1261   if (field->is_extension()) {
1262     MutableExtensionSet(message)->SetRepeatedString(field->number(), index,
1263                                                     value);
1264   } else {
1265     switch (field->options().ctype()) {
1266       default:  // TODO(kenton):  Support other string reps.
1267       case FieldOptions::STRING:
1268         *MutableRepeatedField<std::string>(message, field, index) = value;
1269         break;
1270     }
1271   }
1272 }
1273 
1274 
AddString(Message * message,const FieldDescriptor * field,const std::string & value) const1275 void Reflection::AddString(Message* message, const FieldDescriptor* field,
1276                            const std::string& value) const {
1277   USAGE_CHECK_ALL(AddString, REPEATED, STRING);
1278   if (field->is_extension()) {
1279     MutableExtensionSet(message)->AddString(field->number(), field->type(),
1280                                             value, field);
1281   } else {
1282     switch (field->options().ctype()) {
1283       default:  // TODO(kenton):  Support other string reps.
1284       case FieldOptions::STRING:
1285         *AddField<std::string>(message, field) = value;
1286         break;
1287     }
1288   }
1289 }
1290 
1291 
1292 // -------------------------------------------------------------------
1293 
GetEnum(const Message & message,const FieldDescriptor * field) const1294 const EnumValueDescriptor* Reflection::GetEnum(
1295     const Message& message, const FieldDescriptor* field) const {
1296   // Usage checked by GetEnumValue.
1297   int value = GetEnumValue(message, field);
1298   return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1299 }
1300 
GetEnumValue(const Message & message,const FieldDescriptor * field) const1301 int Reflection::GetEnumValue(const Message& message,
1302                              const FieldDescriptor* field) const {
1303   USAGE_CHECK_ALL(GetEnumValue, SINGULAR, ENUM);
1304 
1305   int32 value;
1306   if (field->is_extension()) {
1307     value = GetExtensionSet(message).GetEnum(
1308         field->number(), field->default_value_enum()->number());
1309   } else {
1310     value = GetField<int>(message, field);
1311   }
1312   return value;
1313 }
1314 
SetEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const1315 void Reflection::SetEnum(Message* message, const FieldDescriptor* field,
1316                          const EnumValueDescriptor* value) const {
1317   // Usage checked by SetEnumValue.
1318   USAGE_CHECK_ENUM_VALUE(SetEnum);
1319   SetEnumValueInternal(message, field, value->number());
1320 }
1321 
SetEnumValue(Message * message,const FieldDescriptor * field,int value) const1322 void Reflection::SetEnumValue(Message* message, const FieldDescriptor* field,
1323                               int value) const {
1324   USAGE_CHECK_ALL(SetEnumValue, SINGULAR, ENUM);
1325   if (!CreateUnknownEnumValues(descriptor_->file())) {
1326     // Check that the value is valid if we don't support direct storage of
1327     // unknown enum values.
1328     const EnumValueDescriptor* value_desc =
1329         field->enum_type()->FindValueByNumber(value);
1330     if (value_desc == nullptr) {
1331       MutableUnknownFields(message)->AddVarint(field->number(), value);
1332       return;
1333     }
1334   }
1335   SetEnumValueInternal(message, field, value);
1336 }
1337 
SetEnumValueInternal(Message * message,const FieldDescriptor * field,int value) const1338 void Reflection::SetEnumValueInternal(Message* message,
1339                                       const FieldDescriptor* field,
1340                                       int value) const {
1341   if (field->is_extension()) {
1342     MutableExtensionSet(message)->SetEnum(field->number(), field->type(), value,
1343                                           field);
1344   } else {
1345     SetField<int>(message, field, value);
1346   }
1347 }
1348 
GetRepeatedEnum(const Message & message,const FieldDescriptor * field,int index) const1349 const EnumValueDescriptor* Reflection::GetRepeatedEnum(
1350     const Message& message, const FieldDescriptor* field, int index) const {
1351   // Usage checked by GetRepeatedEnumValue.
1352   int value = GetRepeatedEnumValue(message, field, index);
1353   return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1354 }
1355 
GetRepeatedEnumValue(const Message & message,const FieldDescriptor * field,int index) const1356 int Reflection::GetRepeatedEnumValue(const Message& message,
1357                                      const FieldDescriptor* field,
1358                                      int index) const {
1359   USAGE_CHECK_ALL(GetRepeatedEnumValue, REPEATED, ENUM);
1360 
1361   int value;
1362   if (field->is_extension()) {
1363     value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
1364   } else {
1365     value = GetRepeatedField<int>(message, field, index);
1366   }
1367   return value;
1368 }
1369 
SetRepeatedEnum(Message * message,const FieldDescriptor * field,int index,const EnumValueDescriptor * value) const1370 void Reflection::SetRepeatedEnum(Message* message, const FieldDescriptor* field,
1371                                  int index,
1372                                  const EnumValueDescriptor* value) const {
1373   // Usage checked by SetRepeatedEnumValue.
1374   USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
1375   SetRepeatedEnumValueInternal(message, field, index, value->number());
1376 }
1377 
SetRepeatedEnumValue(Message * message,const FieldDescriptor * field,int index,int value) const1378 void Reflection::SetRepeatedEnumValue(Message* message,
1379                                       const FieldDescriptor* field, int index,
1380                                       int value) const {
1381   USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
1382   if (!CreateUnknownEnumValues(descriptor_->file())) {
1383     // Check that the value is valid if we don't support direct storage of
1384     // unknown enum values.
1385     const EnumValueDescriptor* value_desc =
1386         field->enum_type()->FindValueByNumber(value);
1387     if (value_desc == nullptr) {
1388       MutableUnknownFields(message)->AddVarint(field->number(), value);
1389       return;
1390     }
1391   }
1392   SetRepeatedEnumValueInternal(message, field, index, value);
1393 }
1394 
SetRepeatedEnumValueInternal(Message * message,const FieldDescriptor * field,int index,int value) const1395 void Reflection::SetRepeatedEnumValueInternal(Message* message,
1396                                               const FieldDescriptor* field,
1397                                               int index, int value) const {
1398   if (field->is_extension()) {
1399     MutableExtensionSet(message)->SetRepeatedEnum(field->number(), index,
1400                                                   value);
1401   } else {
1402     SetRepeatedField<int>(message, field, index, value);
1403   }
1404 }
1405 
AddEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const1406 void Reflection::AddEnum(Message* message, const FieldDescriptor* field,
1407                          const EnumValueDescriptor* value) const {
1408   // Usage checked by AddEnumValue.
1409   USAGE_CHECK_ENUM_VALUE(AddEnum);
1410   AddEnumValueInternal(message, field, value->number());
1411 }
1412 
AddEnumValue(Message * message,const FieldDescriptor * field,int value) const1413 void Reflection::AddEnumValue(Message* message, const FieldDescriptor* field,
1414                               int value) const {
1415   USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
1416   if (!CreateUnknownEnumValues(descriptor_->file())) {
1417     // Check that the value is valid if we don't support direct storage of
1418     // unknown enum values.
1419     const EnumValueDescriptor* value_desc =
1420         field->enum_type()->FindValueByNumber(value);
1421     if (value_desc == nullptr) {
1422       MutableUnknownFields(message)->AddVarint(field->number(), value);
1423       return;
1424     }
1425   }
1426   AddEnumValueInternal(message, field, value);
1427 }
1428 
AddEnumValueInternal(Message * message,const FieldDescriptor * field,int value) const1429 void Reflection::AddEnumValueInternal(Message* message,
1430                                       const FieldDescriptor* field,
1431                                       int value) const {
1432   if (field->is_extension()) {
1433     MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
1434                                           field->options().packed(), value,
1435                                           field);
1436   } else {
1437     AddField<int>(message, field, value);
1438   }
1439 }
1440 
1441 // -------------------------------------------------------------------
1442 
GetMessage(const Message & message,const FieldDescriptor * field,MessageFactory * factory) const1443 const Message& Reflection::GetMessage(const Message& message,
1444                                       const FieldDescriptor* field,
1445                                       MessageFactory* factory) const {
1446   USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
1447 
1448   if (factory == nullptr) factory = message_factory_;
1449 
1450   if (field->is_extension()) {
1451     return static_cast<const Message&>(GetExtensionSet(message).GetMessage(
1452         field->number(), field->message_type(), factory));
1453   } else {
1454     const Message* result = GetRaw<const Message*>(message, field);
1455     if (result == nullptr) {
1456       result = DefaultRaw<const Message*>(field);
1457     }
1458     return *result;
1459   }
1460 }
1461 
MutableMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1462 Message* Reflection::MutableMessage(Message* message,
1463                                     const FieldDescriptor* field,
1464                                     MessageFactory* factory) const {
1465   USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
1466 
1467   if (factory == nullptr) factory = message_factory_;
1468 
1469   if (field->is_extension()) {
1470     return static_cast<Message*>(
1471         MutableExtensionSet(message)->MutableMessage(field, factory));
1472   } else {
1473     Message* result;
1474 
1475     Message** result_holder = MutableRaw<Message*>(message, field);
1476 
1477     if (field->containing_oneof()) {
1478       if (!HasOneofField(*message, field)) {
1479         ClearOneof(message, field->containing_oneof());
1480         result_holder = MutableField<Message*>(message, field);
1481         const Message* default_message = DefaultRaw<const Message*>(field);
1482         *result_holder = default_message->New(message->GetArena());
1483       }
1484     } else {
1485       SetBit(message, field);
1486     }
1487 
1488     if (*result_holder == nullptr) {
1489       const Message* default_message = DefaultRaw<const Message*>(field);
1490       *result_holder = default_message->New(message->GetArena());
1491     }
1492     result = *result_holder;
1493     return result;
1494   }
1495 }
1496 
UnsafeArenaSetAllocatedMessage(Message * message,Message * sub_message,const FieldDescriptor * field) const1497 void Reflection::UnsafeArenaSetAllocatedMessage(
1498     Message* message, Message* sub_message,
1499     const FieldDescriptor* field) const {
1500   USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
1501 
1502   if (field->is_extension()) {
1503     MutableExtensionSet(message)->UnsafeArenaSetAllocatedMessage(
1504         field->number(), field->type(), field, sub_message);
1505   } else {
1506     if (field->containing_oneof()) {
1507       if (sub_message == nullptr) {
1508         ClearOneof(message, field->containing_oneof());
1509         return;
1510       }
1511         ClearOneof(message, field->containing_oneof());
1512         *MutableRaw<Message*>(message, field) = sub_message;
1513       SetOneofCase(message, field);
1514       return;
1515     }
1516 
1517     if (sub_message == nullptr) {
1518       ClearBit(message, field);
1519     } else {
1520       SetBit(message, field);
1521     }
1522     Message** sub_message_holder = MutableRaw<Message*>(message, field);
1523     if (GetArena(message) == nullptr) {
1524       delete *sub_message_holder;
1525     }
1526     *sub_message_holder = sub_message;
1527   }
1528 }
1529 
SetAllocatedMessage(Message * message,Message * sub_message,const FieldDescriptor * field) const1530 void Reflection::SetAllocatedMessage(Message* message, Message* sub_message,
1531                                      const FieldDescriptor* field) const {
1532   // If message and sub-message are in different memory ownership domains
1533   // (different arenas, or one is on heap and one is not), then we may need to
1534   // do a copy.
1535   if (sub_message != nullptr &&
1536       sub_message->GetArena() != message->GetArena()) {
1537     if (sub_message->GetArena() == nullptr && message->GetArena() != nullptr) {
1538       // Case 1: parent is on an arena and child is heap-allocated. We can add
1539       // the child to the arena's Own() list to free on arena destruction, then
1540       // set our pointer.
1541       message->GetArena()->Own(sub_message);
1542       UnsafeArenaSetAllocatedMessage(message, sub_message, field);
1543     } else {
1544       // Case 2: all other cases. We need to make a copy. MutableMessage() will
1545       // either get the existing message object, or instantiate a new one as
1546       // appropriate w.r.t. our arena.
1547       Message* sub_message_copy = MutableMessage(message, field);
1548       sub_message_copy->CopyFrom(*sub_message);
1549     }
1550   } else {
1551     // Same memory ownership domains.
1552     UnsafeArenaSetAllocatedMessage(message, sub_message, field);
1553   }
1554 }
1555 
UnsafeArenaReleaseMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1556 Message* Reflection::UnsafeArenaReleaseMessage(Message* message,
1557                                                const FieldDescriptor* field,
1558                                                MessageFactory* factory) const {
1559   USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
1560 
1561   if (factory == nullptr) factory = message_factory_;
1562 
1563   if (field->is_extension()) {
1564     return static_cast<Message*>(
1565         MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field,
1566                                                                 factory));
1567   } else {
1568     if (!(field->is_repeated() || field->containing_oneof())) {
1569       ClearBit(message, field);
1570     }
1571     if (field->containing_oneof()) {
1572       if (HasOneofField(*message, field)) {
1573         *MutableOneofCase(message, field->containing_oneof()) = 0;
1574       } else {
1575         return nullptr;
1576       }
1577     }
1578     Message** result = MutableRaw<Message*>(message, field);
1579     Message* ret = *result;
1580     *result = nullptr;
1581     return ret;
1582   }
1583 }
1584 
ReleaseMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1585 Message* Reflection::ReleaseMessage(Message* message,
1586                                     const FieldDescriptor* field,
1587                                     MessageFactory* factory) const {
1588   Message* released = UnsafeArenaReleaseMessage(message, field, factory);
1589   if (GetArena(message) != nullptr && released != nullptr) {
1590     Message* copy_from_arena = released->New();
1591     copy_from_arena->CopyFrom(*released);
1592     released = copy_from_arena;
1593   }
1594   return released;
1595 }
1596 
GetRepeatedMessage(const Message & message,const FieldDescriptor * field,int index) const1597 const Message& Reflection::GetRepeatedMessage(const Message& message,
1598                                               const FieldDescriptor* field,
1599                                               int index) const {
1600   USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
1601 
1602   if (field->is_extension()) {
1603     return static_cast<const Message&>(
1604         GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
1605   } else {
1606     if (IsMapFieldInApi(field)) {
1607       return GetRaw<MapFieldBase>(message, field)
1608           .GetRepeatedField()
1609           .Get<GenericTypeHandler<Message> >(index);
1610     } else {
1611       return GetRaw<RepeatedPtrFieldBase>(message, field)
1612           .Get<GenericTypeHandler<Message> >(index);
1613     }
1614   }
1615 }
1616 
MutableRepeatedMessage(Message * message,const FieldDescriptor * field,int index) const1617 Message* Reflection::MutableRepeatedMessage(Message* message,
1618                                             const FieldDescriptor* field,
1619                                             int index) const {
1620   USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
1621 
1622   if (field->is_extension()) {
1623     return static_cast<Message*>(
1624         MutableExtensionSet(message)->MutableRepeatedMessage(field->number(),
1625                                                              index));
1626   } else {
1627     if (IsMapFieldInApi(field)) {
1628       return MutableRaw<MapFieldBase>(message, field)
1629           ->MutableRepeatedField()
1630           ->Mutable<GenericTypeHandler<Message> >(index);
1631     } else {
1632       return MutableRaw<RepeatedPtrFieldBase>(message, field)
1633           ->Mutable<GenericTypeHandler<Message> >(index);
1634     }
1635   }
1636 }
1637 
AddMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1638 Message* Reflection::AddMessage(Message* message, const FieldDescriptor* field,
1639                                 MessageFactory* factory) const {
1640   USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
1641 
1642   if (factory == nullptr) factory = message_factory_;
1643 
1644   if (field->is_extension()) {
1645     return static_cast<Message*>(
1646         MutableExtensionSet(message)->AddMessage(field, factory));
1647   } else {
1648     Message* result = nullptr;
1649 
1650     // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
1651     // know how to allocate one.
1652     RepeatedPtrFieldBase* repeated = nullptr;
1653     if (IsMapFieldInApi(field)) {
1654       repeated =
1655           MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
1656     } else {
1657       repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
1658     }
1659     result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
1660     if (result == nullptr) {
1661       // We must allocate a new object.
1662       const Message* prototype;
1663       if (repeated->size() == 0) {
1664         prototype = factory->GetPrototype(field->message_type());
1665       } else {
1666         prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
1667       }
1668       result = prototype->New(message->GetArena());
1669       // We can guarantee here that repeated and result are either both heap
1670       // allocated or arena owned. So it is safe to call the unsafe version
1671       // of AddAllocated.
1672       repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message> >(result);
1673     }
1674 
1675     return result;
1676   }
1677 }
1678 
AddAllocatedMessage(Message * message,const FieldDescriptor * field,Message * new_entry) const1679 void Reflection::AddAllocatedMessage(Message* message,
1680                                      const FieldDescriptor* field,
1681                                      Message* new_entry) const {
1682   USAGE_CHECK_ALL(AddAllocatedMessage, REPEATED, MESSAGE);
1683 
1684   if (field->is_extension()) {
1685     MutableExtensionSet(message)->AddAllocatedMessage(field, new_entry);
1686   } else {
1687     RepeatedPtrFieldBase* repeated = nullptr;
1688     if (IsMapFieldInApi(field)) {
1689       repeated =
1690           MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
1691     } else {
1692       repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
1693     }
1694     repeated->AddAllocated<GenericTypeHandler<Message> >(new_entry);
1695   }
1696 }
1697 
MutableRawRepeatedField(Message * message,const FieldDescriptor * field,FieldDescriptor::CppType cpptype,int ctype,const Descriptor * desc) const1698 void* Reflection::MutableRawRepeatedField(Message* message,
1699                                           const FieldDescriptor* field,
1700                                           FieldDescriptor::CppType cpptype,
1701                                           int ctype,
1702                                           const Descriptor* desc) const {
1703   USAGE_CHECK_REPEATED("MutableRawRepeatedField");
1704   if (field->cpp_type() != cpptype)
1705     ReportReflectionUsageTypeError(descriptor_, field,
1706                                    "MutableRawRepeatedField", cpptype);
1707   if (desc != nullptr)
1708     GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
1709   if (field->is_extension()) {
1710     return MutableExtensionSet(message)->MutableRawRepeatedField(
1711         field->number(), field->type(), field->is_packed(), field);
1712   } else {
1713     // Trigger transform for MapField
1714     if (IsMapFieldInApi(field)) {
1715       return MutableRawNonOneof<MapFieldBase>(message, field)
1716           ->MutableRepeatedField();
1717     }
1718     return MutableRawNonOneof<void>(message, field);
1719   }
1720 }
1721 
GetRawRepeatedField(const Message & message,const FieldDescriptor * field,FieldDescriptor::CppType cpptype,int ctype,const Descriptor * desc) const1722 const void* Reflection::GetRawRepeatedField(const Message& message,
1723                                             const FieldDescriptor* field,
1724                                             FieldDescriptor::CppType cpptype,
1725                                             int ctype,
1726                                             const Descriptor* desc) const {
1727   USAGE_CHECK_REPEATED("GetRawRepeatedField");
1728   if (field->cpp_type() != cpptype)
1729     ReportReflectionUsageTypeError(descriptor_, field, "GetRawRepeatedField",
1730                                    cpptype);
1731   if (ctype >= 0)
1732     GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
1733   if (desc != nullptr)
1734     GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
1735   if (field->is_extension()) {
1736     // Should use extension_set::GetRawRepeatedField. However, the required
1737     // parameter "default repeated value" is not very easy to get here.
1738     // Map is not supported in extensions, it is acceptable to use
1739     // extension_set::MutableRawRepeatedField which does not change the message.
1740     return MutableExtensionSet(const_cast<Message*>(&message))
1741         ->MutableRawRepeatedField(field->number(), field->type(),
1742                                   field->is_packed(), field);
1743   } else {
1744     // Trigger transform for MapField
1745     if (IsMapFieldInApi(field)) {
1746       return &(GetRawNonOneof<MapFieldBase>(message, field).GetRepeatedField());
1747     }
1748     return &GetRawNonOneof<char>(message, field);
1749   }
1750 }
1751 
GetOneofFieldDescriptor(const Message & message,const OneofDescriptor * oneof_descriptor) const1752 const FieldDescriptor* Reflection::GetOneofFieldDescriptor(
1753     const Message& message, const OneofDescriptor* oneof_descriptor) const {
1754   uint32 field_number = GetOneofCase(message, oneof_descriptor);
1755   if (field_number == 0) {
1756     return nullptr;
1757   }
1758   return descriptor_->FindFieldByNumber(field_number);
1759 }
1760 
ContainsMapKey(const Message & message,const FieldDescriptor * field,const MapKey & key) const1761 bool Reflection::ContainsMapKey(const Message& message,
1762                                 const FieldDescriptor* field,
1763                                 const MapKey& key) const {
1764   USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue",
1765               "Field is not a map field.");
1766   return GetRaw<MapFieldBase>(message, field).ContainsMapKey(key);
1767 }
1768 
InsertOrLookupMapValue(Message * message,const FieldDescriptor * field,const MapKey & key,MapValueRef * val) const1769 bool Reflection::InsertOrLookupMapValue(Message* message,
1770                                         const FieldDescriptor* field,
1771                                         const MapKey& key,
1772                                         MapValueRef* val) const {
1773   USAGE_CHECK(IsMapFieldInApi(field), "InsertOrLookupMapValue",
1774               "Field is not a map field.");
1775   val->SetType(field->message_type()->FindFieldByName("value")->cpp_type());
1776   return MutableRaw<MapFieldBase>(message, field)
1777       ->InsertOrLookupMapValue(key, val);
1778 }
1779 
DeleteMapValue(Message * message,const FieldDescriptor * field,const MapKey & key) const1780 bool Reflection::DeleteMapValue(Message* message, const FieldDescriptor* field,
1781                                 const MapKey& key) const {
1782   USAGE_CHECK(IsMapFieldInApi(field), "DeleteMapValue",
1783               "Field is not a map field.");
1784   return MutableRaw<MapFieldBase>(message, field)->DeleteMapValue(key);
1785 }
1786 
MapBegin(Message * message,const FieldDescriptor * field) const1787 MapIterator Reflection::MapBegin(Message* message,
1788                                  const FieldDescriptor* field) const {
1789   USAGE_CHECK(IsMapFieldInApi(field), "MapBegin", "Field is not a map field.");
1790   MapIterator iter(message, field);
1791   GetRaw<MapFieldBase>(*message, field).MapBegin(&iter);
1792   return iter;
1793 }
1794 
MapEnd(Message * message,const FieldDescriptor * field) const1795 MapIterator Reflection::MapEnd(Message* message,
1796                                const FieldDescriptor* field) const {
1797   USAGE_CHECK(IsMapFieldInApi(field), "MapEnd", "Field is not a map field.");
1798   MapIterator iter(message, field);
1799   GetRaw<MapFieldBase>(*message, field).MapEnd(&iter);
1800   return iter;
1801 }
1802 
MapSize(const Message & message,const FieldDescriptor * field) const1803 int Reflection::MapSize(const Message& message,
1804                         const FieldDescriptor* field) const {
1805   USAGE_CHECK(IsMapFieldInApi(field), "MapSize", "Field is not a map field.");
1806   return GetRaw<MapFieldBase>(message, field).size();
1807 }
1808 
1809 // -----------------------------------------------------------------------------
1810 
FindKnownExtensionByName(const std::string & name) const1811 const FieldDescriptor* Reflection::FindKnownExtensionByName(
1812     const std::string& name) const {
1813   if (!schema_.HasExtensionSet()) return nullptr;
1814   return descriptor_pool_->FindExtensionByPrintableName(descriptor_, name);
1815 }
1816 
FindKnownExtensionByNumber(int number) const1817 const FieldDescriptor* Reflection::FindKnownExtensionByNumber(
1818     int number) const {
1819   if (!schema_.HasExtensionSet()) return nullptr;
1820   return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
1821 }
1822 
SupportsUnknownEnumValues() const1823 bool Reflection::SupportsUnknownEnumValues() const {
1824   return CreateUnknownEnumValues(descriptor_->file());
1825 }
1826 
1827 // ===================================================================
1828 // Some private helpers.
1829 
1830 // These simple template accessors obtain pointers (or references) to
1831 // the given field.
1832 
1833 template <class Type>
GetRawNonOneof(const Message & message,const FieldDescriptor * field) const1834 const Type& Reflection::GetRawNonOneof(const Message& message,
1835                                        const FieldDescriptor* field) const {
1836   return GetConstRefAtOffset<Type>(message,
1837                                    schema_.GetFieldOffsetNonOneof(field));
1838 }
1839 
1840 template <class Type>
MutableRawNonOneof(Message * message,const FieldDescriptor * field) const1841 Type* Reflection::MutableRawNonOneof(Message* message,
1842                                      const FieldDescriptor* field) const {
1843   return GetPointerAtOffset<Type>(message,
1844                                   schema_.GetFieldOffsetNonOneof(field));
1845 }
1846 
1847 template <typename Type>
GetRaw(const Message & message,const FieldDescriptor * field) const1848 const Type& Reflection::GetRaw(const Message& message,
1849                                const FieldDescriptor* field) const {
1850   if (field->containing_oneof() && !HasOneofField(message, field)) {
1851     return DefaultRaw<Type>(field);
1852   }
1853   return GetConstRefAtOffset<Type>(message, schema_.GetFieldOffset(field));
1854 }
1855 
IsInlined(const FieldDescriptor * field) const1856 bool Reflection::IsInlined(const FieldDescriptor* field) const {
1857   return schema_.IsFieldInlined(field);
1858 }
1859 
1860 template <typename Type>
MutableRaw(Message * message,const FieldDescriptor * field) const1861 Type* Reflection::MutableRaw(Message* message,
1862                              const FieldDescriptor* field) const {
1863   return GetPointerAtOffset<Type>(message, schema_.GetFieldOffset(field));
1864 }
1865 
GetHasBits(const Message & message) const1866 const uint32* Reflection::GetHasBits(const Message& message) const {
1867   GOOGLE_DCHECK(schema_.HasHasbits());
1868   return &GetConstRefAtOffset<uint32>(message, schema_.HasBitsOffset());
1869 }
1870 
MutableHasBits(Message * message) const1871 uint32* Reflection::MutableHasBits(Message* message) const {
1872   GOOGLE_DCHECK(schema_.HasHasbits());
1873   return GetPointerAtOffset<uint32>(message, schema_.HasBitsOffset());
1874 }
1875 
GetOneofCase(const Message & message,const OneofDescriptor * oneof_descriptor) const1876 uint32 Reflection::GetOneofCase(const Message& message,
1877                                 const OneofDescriptor* oneof_descriptor) const {
1878   return GetConstRefAtOffset<uint32>(
1879       message, schema_.GetOneofCaseOffset(oneof_descriptor));
1880 }
1881 
MutableOneofCase(Message * message,const OneofDescriptor * oneof_descriptor) const1882 uint32* Reflection::MutableOneofCase(
1883     Message* message, const OneofDescriptor* oneof_descriptor) const {
1884   return GetPointerAtOffset<uint32>(
1885       message, schema_.GetOneofCaseOffset(oneof_descriptor));
1886 }
1887 
GetExtensionSet(const Message & message) const1888 const ExtensionSet& Reflection::GetExtensionSet(const Message& message) const {
1889   return GetConstRefAtOffset<ExtensionSet>(message,
1890                                            schema_.GetExtensionSetOffset());
1891 }
1892 
MutableExtensionSet(Message * message) const1893 ExtensionSet* Reflection::MutableExtensionSet(Message* message) const {
1894   return GetPointerAtOffset<ExtensionSet>(message,
1895                                           schema_.GetExtensionSetOffset());
1896 }
1897 
GetArena(Message * message) const1898 Arena* Reflection::GetArena(Message* message) const {
1899   return GetInternalMetadataWithArena(*message).arena();
1900 }
1901 
GetInternalMetadataWithArena(const Message & message) const1902 const InternalMetadataWithArena& Reflection::GetInternalMetadataWithArena(
1903     const Message& message) const {
1904   return GetConstRefAtOffset<InternalMetadataWithArena>(
1905       message, schema_.GetMetadataOffset());
1906 }
1907 
MutableInternalMetadataWithArena(Message * message) const1908 InternalMetadataWithArena* Reflection::MutableInternalMetadataWithArena(
1909     Message* message) const {
1910   return GetPointerAtOffset<InternalMetadataWithArena>(
1911       message, schema_.GetMetadataOffset());
1912 }
1913 
1914 template <typename Type>
DefaultRaw(const FieldDescriptor * field) const1915 const Type& Reflection::DefaultRaw(const FieldDescriptor* field) const {
1916   return *reinterpret_cast<const Type*>(schema_.GetFieldDefault(field));
1917 }
1918 
1919 // Simple accessors for manipulating has_bits_.
HasBit(const Message & message,const FieldDescriptor * field) const1920 bool Reflection::HasBit(const Message& message,
1921                         const FieldDescriptor* field) const {
1922   GOOGLE_DCHECK(!field->options().weak());
1923   if (schema_.HasHasbits()) {
1924     return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field));
1925   }
1926 
1927   // proto3: no has-bits. All fields present except messages, which are
1928   // present only if their message-field pointer is non-null.
1929   if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1930     return !schema_.IsDefaultInstance(message) &&
1931            GetRaw<const Message*>(message, field) != nullptr;
1932   } else {
1933     // Non-message field (and non-oneof, since that was handled in HasField()
1934     // before calling us), and singular (again, checked in HasField). So, this
1935     // field must be a scalar.
1936 
1937     // Scalar primitive (numeric or string/bytes) fields are present if
1938     // their value is non-zero (numeric) or non-empty (string/bytes). N.B.:
1939     // we must use this definition here, rather than the "scalar fields
1940     // always present" in the proto3 docs, because MergeFrom() semantics
1941     // require presence as "present on wire", and reflection-based merge
1942     // (which uses HasField()) needs to be consistent with this.
1943     switch (field->cpp_type()) {
1944       case FieldDescriptor::CPPTYPE_STRING:
1945         switch (field->options().ctype()) {
1946           default: {
1947             if (IsInlined(field)) {
1948               return !GetField<InlinedStringField>(message, field)
1949                           .GetNoArena()
1950                           .empty();
1951             }
1952             return GetField<ArenaStringPtr>(message, field).Get().size() > 0;
1953           }
1954         }
1955         return false;
1956       case FieldDescriptor::CPPTYPE_BOOL:
1957         return GetRaw<bool>(message, field) != false;
1958       case FieldDescriptor::CPPTYPE_INT32:
1959         return GetRaw<int32>(message, field) != 0;
1960       case FieldDescriptor::CPPTYPE_INT64:
1961         return GetRaw<int64>(message, field) != 0;
1962       case FieldDescriptor::CPPTYPE_UINT32:
1963         return GetRaw<uint32>(message, field) != 0;
1964       case FieldDescriptor::CPPTYPE_UINT64:
1965         return GetRaw<uint64>(message, field) != 0;
1966       case FieldDescriptor::CPPTYPE_FLOAT:
1967         return GetRaw<float>(message, field) != 0.0;
1968       case FieldDescriptor::CPPTYPE_DOUBLE:
1969         return GetRaw<double>(message, field) != 0.0;
1970       case FieldDescriptor::CPPTYPE_ENUM:
1971         return GetRaw<int>(message, field) != 0;
1972       case FieldDescriptor::CPPTYPE_MESSAGE:
1973         // handled above; avoid warning
1974         break;
1975     }
1976     GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit().";
1977     return false;
1978   }
1979 }
1980 
SetBit(Message * message,const FieldDescriptor * field) const1981 void Reflection::SetBit(Message* message, const FieldDescriptor* field) const {
1982   GOOGLE_DCHECK(!field->options().weak());
1983   if (!schema_.HasHasbits()) {
1984     return;
1985   }
1986   const uint32 index = schema_.HasBitIndex(field);
1987   MutableHasBits(message)[index / 32] |=
1988       (static_cast<uint32>(1) << (index % 32));
1989 }
1990 
ClearBit(Message * message,const FieldDescriptor * field) const1991 void Reflection::ClearBit(Message* message,
1992                           const FieldDescriptor* field) const {
1993   GOOGLE_DCHECK(!field->options().weak());
1994   if (!schema_.HasHasbits()) {
1995     return;
1996   }
1997   const uint32 index = schema_.HasBitIndex(field);
1998   MutableHasBits(message)[index / 32] &=
1999       ~(static_cast<uint32>(1) << (index % 32));
2000 }
2001 
SwapBit(Message * message1,Message * message2,const FieldDescriptor * field) const2002 void Reflection::SwapBit(Message* message1, Message* message2,
2003                          const FieldDescriptor* field) const {
2004   GOOGLE_DCHECK(!field->options().weak());
2005   if (!schema_.HasHasbits()) {
2006     return;
2007   }
2008   bool temp_has_bit = HasBit(*message1, field);
2009   if (HasBit(*message2, field)) {
2010     SetBit(message1, field);
2011   } else {
2012     ClearBit(message1, field);
2013   }
2014   if (temp_has_bit) {
2015     SetBit(message2, field);
2016   } else {
2017     ClearBit(message2, field);
2018   }
2019 }
2020 
HasOneof(const Message & message,const OneofDescriptor * oneof_descriptor) const2021 bool Reflection::HasOneof(const Message& message,
2022                           const OneofDescriptor* oneof_descriptor) const {
2023   return (GetOneofCase(message, oneof_descriptor) > 0);
2024 }
2025 
HasOneofField(const Message & message,const FieldDescriptor * field) const2026 bool Reflection::HasOneofField(const Message& message,
2027                                const FieldDescriptor* field) const {
2028   return (GetOneofCase(message, field->containing_oneof()) == field->number());
2029 }
2030 
SetOneofCase(Message * message,const FieldDescriptor * field) const2031 void Reflection::SetOneofCase(Message* message,
2032                               const FieldDescriptor* field) const {
2033   *MutableOneofCase(message, field->containing_oneof()) = field->number();
2034 }
2035 
ClearOneofField(Message * message,const FieldDescriptor * field) const2036 void Reflection::ClearOneofField(Message* message,
2037                                  const FieldDescriptor* field) const {
2038   if (HasOneofField(*message, field)) {
2039     ClearOneof(message, field->containing_oneof());
2040   }
2041 }
2042 
ClearOneof(Message * message,const OneofDescriptor * oneof_descriptor) const2043 void Reflection::ClearOneof(Message* message,
2044                             const OneofDescriptor* oneof_descriptor) const {
2045   // TODO(jieluo): Consider to cache the unused object instead of deleting
2046   // it. It will be much faster if an application switches a lot from
2047   // a few oneof fields.  Time/space tradeoff
2048   uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
2049   if (oneof_case > 0) {
2050     const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
2051     if (GetArena(message) == nullptr) {
2052       switch (field->cpp_type()) {
2053         case FieldDescriptor::CPPTYPE_STRING: {
2054           switch (field->options().ctype()) {
2055             default:  // TODO(kenton):  Support other string reps.
2056             case FieldOptions::STRING: {
2057               const std::string* default_ptr =
2058                   &DefaultRaw<ArenaStringPtr>(field).Get();
2059               MutableField<ArenaStringPtr>(message, field)
2060                   ->Destroy(default_ptr, GetArena(message));
2061               break;
2062             }
2063           }
2064           break;
2065         }
2066 
2067         case FieldDescriptor::CPPTYPE_MESSAGE:
2068           delete *MutableRaw<Message*>(message, field);
2069           break;
2070         default:
2071           break;
2072       }
2073     }
2074 
2075     *MutableOneofCase(message, oneof_descriptor) = 0;
2076   }
2077 }
2078 
2079 #define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE)                               \
2080   template <>                                                           \
2081   const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>(        \
2082       const Message& message, const FieldDescriptor* field) const {     \
2083     return *static_cast<RepeatedField<TYPE>*>(MutableRawRepeatedField(  \
2084         const_cast<Message*>(&message), field, CPPTYPE, CTYPE, NULL));  \
2085   }                                                                     \
2086                                                                         \
2087   template <>                                                           \
2088   RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>(          \
2089       Message * message, const FieldDescriptor* field) const {          \
2090     return static_cast<RepeatedField<TYPE>*>(                           \
2091         MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL)); \
2092   }
2093 
2094 HANDLE_TYPE(int32, FieldDescriptor::CPPTYPE_INT32, -1);
2095 HANDLE_TYPE(int64, FieldDescriptor::CPPTYPE_INT64, -1);
2096 HANDLE_TYPE(uint32, FieldDescriptor::CPPTYPE_UINT32, -1);
2097 HANDLE_TYPE(uint64, FieldDescriptor::CPPTYPE_UINT64, -1);
2098 HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1);
2099 HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1);
2100 HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1);
2101 
2102 
2103 #undef HANDLE_TYPE
2104 
MutableRawRepeatedString(Message * message,const FieldDescriptor * field,bool is_string) const2105 void* Reflection::MutableRawRepeatedString(Message* message,
2106                                            const FieldDescriptor* field,
2107                                            bool is_string) const {
2108   return MutableRawRepeatedField(message, field,
2109                                  FieldDescriptor::CPPTYPE_STRING,
2110                                  FieldOptions::STRING, NULL);
2111 }
2112 
2113 // Template implementations of basic accessors.  Inline because each
2114 // template instance is only called from one location.  These are
2115 // used for all types except messages.
2116 template <typename Type>
GetField(const Message & message,const FieldDescriptor * field) const2117 const Type& Reflection::GetField(const Message& message,
2118                                  const FieldDescriptor* field) const {
2119   return GetRaw<Type>(message, field);
2120 }
2121 
2122 template <typename Type>
SetField(Message * message,const FieldDescriptor * field,const Type & value) const2123 void Reflection::SetField(Message* message, const FieldDescriptor* field,
2124                           const Type& value) const {
2125   if (field->containing_oneof() && !HasOneofField(*message, field)) {
2126     ClearOneof(message, field->containing_oneof());
2127   }
2128   *MutableRaw<Type>(message, field) = value;
2129   field->containing_oneof() ? SetOneofCase(message, field)
2130                             : SetBit(message, field);
2131 }
2132 
2133 template <typename Type>
MutableField(Message * message,const FieldDescriptor * field) const2134 Type* Reflection::MutableField(Message* message,
2135                                const FieldDescriptor* field) const {
2136   field->containing_oneof() ? SetOneofCase(message, field)
2137                             : SetBit(message, field);
2138   return MutableRaw<Type>(message, field);
2139 }
2140 
2141 template <typename Type>
GetRepeatedField(const Message & message,const FieldDescriptor * field,int index) const2142 const Type& Reflection::GetRepeatedField(const Message& message,
2143                                          const FieldDescriptor* field,
2144                                          int index) const {
2145   return GetRaw<RepeatedField<Type> >(message, field).Get(index);
2146 }
2147 
2148 template <typename Type>
GetRepeatedPtrField(const Message & message,const FieldDescriptor * field,int index) const2149 const Type& Reflection::GetRepeatedPtrField(const Message& message,
2150                                             const FieldDescriptor* field,
2151                                             int index) const {
2152   return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
2153 }
2154 
2155 template <typename Type>
SetRepeatedField(Message * message,const FieldDescriptor * field,int index,Type value) const2156 void Reflection::SetRepeatedField(Message* message,
2157                                   const FieldDescriptor* field, int index,
2158                                   Type value) const {
2159   MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
2160 }
2161 
2162 template <typename Type>
MutableRepeatedField(Message * message,const FieldDescriptor * field,int index) const2163 Type* Reflection::MutableRepeatedField(Message* message,
2164                                        const FieldDescriptor* field,
2165                                        int index) const {
2166   RepeatedPtrField<Type>* repeated =
2167       MutableRaw<RepeatedPtrField<Type> >(message, field);
2168   return repeated->Mutable(index);
2169 }
2170 
2171 template <typename Type>
AddField(Message * message,const FieldDescriptor * field,const Type & value) const2172 void Reflection::AddField(Message* message, const FieldDescriptor* field,
2173                           const Type& value) const {
2174   MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
2175 }
2176 
2177 template <typename Type>
AddField(Message * message,const FieldDescriptor * field) const2178 Type* Reflection::AddField(Message* message,
2179                            const FieldDescriptor* field) const {
2180   RepeatedPtrField<Type>* repeated =
2181       MutableRaw<RepeatedPtrField<Type> >(message, field);
2182   return repeated->Add();
2183 }
2184 
GetMessageFactory() const2185 MessageFactory* Reflection::GetMessageFactory() const {
2186   return message_factory_;
2187 }
2188 
RepeatedFieldData(Message * message,const FieldDescriptor * field,FieldDescriptor::CppType cpp_type,const Descriptor * message_type) const2189 void* Reflection::RepeatedFieldData(Message* message,
2190                                     const FieldDescriptor* field,
2191                                     FieldDescriptor::CppType cpp_type,
2192                                     const Descriptor* message_type) const {
2193   GOOGLE_CHECK(field->is_repeated());
2194   GOOGLE_CHECK(field->cpp_type() == cpp_type ||
2195         (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
2196          cpp_type == FieldDescriptor::CPPTYPE_INT32))
2197       << "The type parameter T in RepeatedFieldRef<T> API doesn't match "
2198       << "the actual field type (for enums T should be the generated enum "
2199       << "type or int32).";
2200   if (message_type != nullptr) {
2201     GOOGLE_CHECK_EQ(message_type, field->message_type());
2202   }
2203   if (field->is_extension()) {
2204     return MutableExtensionSet(message)->MutableRawRepeatedField(
2205         field->number(), field->type(), field->is_packed(), field);
2206   } else {
2207     return MutableRawNonOneof<char>(message, field);
2208   }
2209 }
2210 
MutableMapData(Message * message,const FieldDescriptor * field) const2211 MapFieldBase* Reflection::MutableMapData(Message* message,
2212                                          const FieldDescriptor* field) const {
2213   USAGE_CHECK(IsMapFieldInApi(field), "GetMapData",
2214               "Field is not a map field.");
2215   return MutableRaw<MapFieldBase>(message, field);
2216 }
2217 
GetMapData(const Message & message,const FieldDescriptor * field) const2218 const MapFieldBase* Reflection::GetMapData(const Message& message,
2219                                            const FieldDescriptor* field) const {
2220   USAGE_CHECK(IsMapFieldInApi(field), "GetMapData",
2221               "Field is not a map field.");
2222   return &(GetRaw<MapFieldBase>(message, field));
2223 }
2224 
2225 namespace {
2226 
2227 // Helper function to transform migration schema into reflection schema.
MigrationToReflectionSchema(const Message * const * default_instance,const uint32 * offsets,MigrationSchema migration_schema)2228 ReflectionSchema MigrationToReflectionSchema(
2229     const Message* const* default_instance, const uint32* offsets,
2230     MigrationSchema migration_schema) {
2231   ReflectionSchema result;
2232   result.default_instance_ = *default_instance;
2233   // First 6 offsets are offsets to the special fields. The following offsets
2234   // are the proto fields.
2235   result.offsets_ = offsets + migration_schema.offsets_index + 5;
2236   result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index;
2237   result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0];
2238   result.metadata_offset_ = offsets[migration_schema.offsets_index + 1];
2239   result.extensions_offset_ = offsets[migration_schema.offsets_index + 2];
2240   result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3];
2241   result.object_size_ = migration_schema.object_size;
2242   result.weak_field_map_offset_ = offsets[migration_schema.offsets_index + 4];
2243   return result;
2244 }
2245 
2246 }  // namespace
2247 
2248 class AssignDescriptorsHelper {
2249  public:
AssignDescriptorsHelper(MessageFactory * factory,Metadata * file_level_metadata,const EnumDescriptor ** file_level_enum_descriptors,const MigrationSchema * schemas,const Message * const * default_instance_data,const uint32 * offsets)2250   AssignDescriptorsHelper(MessageFactory* factory,
2251                           Metadata* file_level_metadata,
2252                           const EnumDescriptor** file_level_enum_descriptors,
2253                           const MigrationSchema* schemas,
2254                           const Message* const* default_instance_data,
2255                           const uint32* offsets)
2256       : factory_(factory),
2257         file_level_metadata_(file_level_metadata),
2258         file_level_enum_descriptors_(file_level_enum_descriptors),
2259         schemas_(schemas),
2260         default_instance_data_(default_instance_data),
2261         offsets_(offsets) {}
2262 
AssignMessageDescriptor(const Descriptor * descriptor)2263   void AssignMessageDescriptor(const Descriptor* descriptor) {
2264     for (int i = 0; i < descriptor->nested_type_count(); i++) {
2265       AssignMessageDescriptor(descriptor->nested_type(i));
2266     }
2267 
2268     file_level_metadata_->descriptor = descriptor;
2269 
2270     file_level_metadata_->reflection =
2271         new Reflection(descriptor,
2272                        MigrationToReflectionSchema(default_instance_data_,
2273                                                    offsets_, *schemas_),
2274                        DescriptorPool::internal_generated_pool(), factory_);
2275     for (int i = 0; i < descriptor->enum_type_count(); i++) {
2276       AssignEnumDescriptor(descriptor->enum_type(i));
2277     }
2278     schemas_++;
2279     default_instance_data_++;
2280     file_level_metadata_++;
2281   }
2282 
AssignEnumDescriptor(const EnumDescriptor * descriptor)2283   void AssignEnumDescriptor(const EnumDescriptor* descriptor) {
2284     *file_level_enum_descriptors_ = descriptor;
2285     file_level_enum_descriptors_++;
2286   }
2287 
GetCurrentMetadataPtr() const2288   const Metadata* GetCurrentMetadataPtr() const { return file_level_metadata_; }
2289 
2290  private:
2291   MessageFactory* factory_;
2292   Metadata* file_level_metadata_;
2293   const EnumDescriptor** file_level_enum_descriptors_;
2294   const MigrationSchema* schemas_;
2295   const Message* const* default_instance_data_;
2296   const uint32* offsets_;
2297 };
2298 
2299 namespace {
2300 
2301 // We have the routines that assign descriptors and build reflection
2302 // automatically delete the allocated reflection. MetadataOwner owns
2303 // all the allocated reflection instances.
2304 struct MetadataOwner {
~MetadataOwnergoogle::protobuf::__anonfa96d48c0511::MetadataOwner2305   ~MetadataOwner() {
2306     for (auto range : metadata_arrays_) {
2307       for (const Metadata* m = range.first; m < range.second; m++) {
2308         delete m->reflection;
2309       }
2310     }
2311   }
2312 
AddArraygoogle::protobuf::__anonfa96d48c0511::MetadataOwner2313   void AddArray(const Metadata* begin, const Metadata* end) {
2314     mu_.Lock();
2315     metadata_arrays_.push_back(std::make_pair(begin, end));
2316     mu_.Unlock();
2317   }
2318 
Instancegoogle::protobuf::__anonfa96d48c0511::MetadataOwner2319   static MetadataOwner* Instance() {
2320     static MetadataOwner* res = OnShutdownDelete(new MetadataOwner);
2321     return res;
2322   }
2323 
2324  private:
2325   MetadataOwner() = default;  // private because singleton
2326 
2327   WrappedMutex mu_;
2328   std::vector<std::pair<const Metadata*, const Metadata*> > metadata_arrays_;
2329 };
2330 
AssignDescriptorsImpl(const DescriptorTable * table)2331 void AssignDescriptorsImpl(const DescriptorTable* table) {
2332   // Ensure the file descriptor is added to the pool.
2333   {
2334     // This only happens once per proto file. So a global mutex to serialize
2335     // calls to AddDescriptors.
2336     static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED};
2337     mu.Lock();
2338     AddDescriptors(table);
2339     mu.Unlock();
2340   }
2341   // Fill the arrays with pointers to descriptors and reflection classes.
2342   const FileDescriptor* file =
2343       DescriptorPool::internal_generated_pool()->FindFileByName(
2344           table->filename);
2345   GOOGLE_CHECK(file != nullptr);
2346 
2347   MessageFactory* factory = MessageFactory::generated_factory();
2348 
2349   AssignDescriptorsHelper helper(
2350       factory, table->file_level_metadata, table->file_level_enum_descriptors,
2351       table->schemas, table->default_instances, table->offsets);
2352 
2353   for (int i = 0; i < file->message_type_count(); i++) {
2354     helper.AssignMessageDescriptor(file->message_type(i));
2355   }
2356 
2357   for (int i = 0; i < file->enum_type_count(); i++) {
2358     helper.AssignEnumDescriptor(file->enum_type(i));
2359   }
2360   if (file->options().cc_generic_services()) {
2361     for (int i = 0; i < file->service_count(); i++) {
2362       table->file_level_service_descriptors[i] = file->service(i);
2363     }
2364   }
2365   MetadataOwner::Instance()->AddArray(table->file_level_metadata,
2366                                       helper.GetCurrentMetadataPtr());
2367 }
2368 
AddDescriptorsImpl(const DescriptorTable * table)2369 void AddDescriptorsImpl(const DescriptorTable* table) {
2370   // Reflection refers to the default instances so make sure they are
2371   // initialized.
2372   for (int i = 0; i < table->num_sccs; i++) {
2373     internal::InitSCC(table->init_default_instances[i]);
2374   }
2375 
2376   // Ensure all dependent descriptors are registered to the generated descriptor
2377   // pool and message factory.
2378   for (int i = 0; i < table->num_deps; i++) {
2379     // In case of weak fields deps[i] could be null.
2380     if (table->deps[i]) AddDescriptors(table->deps[i]);
2381   }
2382 
2383   // Register the descriptor of this file.
2384   DescriptorPool::InternalAddGeneratedFile(table->descriptor, table->size);
2385   MessageFactory::InternalRegisterGeneratedFile(table);
2386 }
2387 
2388 }  // namespace
2389 
2390 // Separate function because it needs to be a friend of
2391 // Reflection
RegisterAllTypesInternal(const Metadata * file_level_metadata,int size)2392 void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) {
2393   for (int i = 0; i < size; i++) {
2394     const Reflection* reflection = file_level_metadata[i].reflection;
2395     MessageFactory::InternalRegisterGeneratedMessage(
2396         file_level_metadata[i].descriptor,
2397         reflection->schema_.default_instance_);
2398   }
2399 }
2400 
2401 namespace internal {
2402 
AssignDescriptors(const DescriptorTable * table)2403 void AssignDescriptors(const DescriptorTable* table) {
2404   call_once(*table->once, AssignDescriptorsImpl, table);
2405 }
2406 
AddDescriptors(const DescriptorTable * table)2407 void AddDescriptors(const DescriptorTable* table) {
2408   // AddDescriptors is not thread safe. Callers need to ensure calls are
2409   // properly serialized. This function is only called pre-main by global
2410   // descriptors and we can assume single threaded access or it's called
2411   // by AssignDescriptorImpl which uses a mutex to sequence calls.
2412   if (*table->is_initialized) return;
2413   *table->is_initialized = true;
2414   AddDescriptorsImpl(table);
2415 }
2416 
RegisterFileLevelMetadata(const DescriptorTable * table)2417 void RegisterFileLevelMetadata(const DescriptorTable* table) {
2418   AssignDescriptors(table);
2419   RegisterAllTypesInternal(table->file_level_metadata, table->num_messages);
2420 }
2421 
UnknownFieldSetSerializer(const uint8 * base,uint32 offset,uint32 tag,uint32 has_offset,io::CodedOutputStream * output)2422 void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag,
2423                                uint32 has_offset,
2424                                io::CodedOutputStream* output) {
2425   const void* ptr = base + offset;
2426   const InternalMetadataWithArena* metadata =
2427       static_cast<const InternalMetadataWithArena*>(ptr);
2428   if (metadata->have_unknown_fields()) {
2429     internal::WireFormat::SerializeUnknownFields(metadata->unknown_fields(),
2430                                                  output);
2431   }
2432 }
2433 
2434 }  // namespace internal
2435 }  // namespace protobuf
2436 }  // namespace google
2437