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::__anonf2ed1b540311::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,std::string value) const1193 void Reflection::SetString(Message* message, const FieldDescriptor* field,
1194                            std::string value) const {
1195   USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
1196   if (field->is_extension()) {
1197     return MutableExtensionSet(message)->SetString(
1198         field->number(), field->type(), std::move(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, std::move(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(std::move(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,std::string value) const1257 void Reflection::SetRepeatedString(Message* message,
1258                                    const FieldDescriptor* field, int index,
1259                                    std::string value) const {
1260   USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
1261   if (field->is_extension()) {
1262     MutableExtensionSet(message)->SetRepeatedString(field->number(), index,
1263                                                     std::move(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)
1269             ->assign(std::move(value));
1270         break;
1271     }
1272   }
1273 }
1274 
1275 
AddString(Message * message,const FieldDescriptor * field,std::string value) const1276 void Reflection::AddString(Message* message, const FieldDescriptor* field,
1277                            std::string value) const {
1278   USAGE_CHECK_ALL(AddString, REPEATED, STRING);
1279   if (field->is_extension()) {
1280     MutableExtensionSet(message)->AddString(field->number(), field->type(),
1281                                             std::move(value), field);
1282   } else {
1283     switch (field->options().ctype()) {
1284       default:  // TODO(kenton):  Support other string reps.
1285       case FieldOptions::STRING:
1286         AddField<std::string>(message, field)->assign(std::move(value));
1287         break;
1288     }
1289   }
1290 }
1291 
1292 
1293 // -------------------------------------------------------------------
1294 
GetEnum(const Message & message,const FieldDescriptor * field) const1295 const EnumValueDescriptor* Reflection::GetEnum(
1296     const Message& message, const FieldDescriptor* field) const {
1297   // Usage checked by GetEnumValue.
1298   int value = GetEnumValue(message, field);
1299   return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1300 }
1301 
GetEnumValue(const Message & message,const FieldDescriptor * field) const1302 int Reflection::GetEnumValue(const Message& message,
1303                              const FieldDescriptor* field) const {
1304   USAGE_CHECK_ALL(GetEnumValue, SINGULAR, ENUM);
1305 
1306   int32 value;
1307   if (field->is_extension()) {
1308     value = GetExtensionSet(message).GetEnum(
1309         field->number(), field->default_value_enum()->number());
1310   } else {
1311     value = GetField<int>(message, field);
1312   }
1313   return value;
1314 }
1315 
SetEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const1316 void Reflection::SetEnum(Message* message, const FieldDescriptor* field,
1317                          const EnumValueDescriptor* value) const {
1318   // Usage checked by SetEnumValue.
1319   USAGE_CHECK_ENUM_VALUE(SetEnum);
1320   SetEnumValueInternal(message, field, value->number());
1321 }
1322 
SetEnumValue(Message * message,const FieldDescriptor * field,int value) const1323 void Reflection::SetEnumValue(Message* message, const FieldDescriptor* field,
1324                               int value) const {
1325   USAGE_CHECK_ALL(SetEnumValue, SINGULAR, ENUM);
1326   if (!CreateUnknownEnumValues(descriptor_->file())) {
1327     // Check that the value is valid if we don't support direct storage of
1328     // unknown enum values.
1329     const EnumValueDescriptor* value_desc =
1330         field->enum_type()->FindValueByNumber(value);
1331     if (value_desc == nullptr) {
1332       MutableUnknownFields(message)->AddVarint(field->number(), value);
1333       return;
1334     }
1335   }
1336   SetEnumValueInternal(message, field, value);
1337 }
1338 
SetEnumValueInternal(Message * message,const FieldDescriptor * field,int value) const1339 void Reflection::SetEnumValueInternal(Message* message,
1340                                       const FieldDescriptor* field,
1341                                       int value) const {
1342   if (field->is_extension()) {
1343     MutableExtensionSet(message)->SetEnum(field->number(), field->type(), value,
1344                                           field);
1345   } else {
1346     SetField<int>(message, field, value);
1347   }
1348 }
1349 
GetRepeatedEnum(const Message & message,const FieldDescriptor * field,int index) const1350 const EnumValueDescriptor* Reflection::GetRepeatedEnum(
1351     const Message& message, const FieldDescriptor* field, int index) const {
1352   // Usage checked by GetRepeatedEnumValue.
1353   int value = GetRepeatedEnumValue(message, field, index);
1354   return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1355 }
1356 
GetRepeatedEnumValue(const Message & message,const FieldDescriptor * field,int index) const1357 int Reflection::GetRepeatedEnumValue(const Message& message,
1358                                      const FieldDescriptor* field,
1359                                      int index) const {
1360   USAGE_CHECK_ALL(GetRepeatedEnumValue, REPEATED, ENUM);
1361 
1362   int value;
1363   if (field->is_extension()) {
1364     value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
1365   } else {
1366     value = GetRepeatedField<int>(message, field, index);
1367   }
1368   return value;
1369 }
1370 
SetRepeatedEnum(Message * message,const FieldDescriptor * field,int index,const EnumValueDescriptor * value) const1371 void Reflection::SetRepeatedEnum(Message* message, const FieldDescriptor* field,
1372                                  int index,
1373                                  const EnumValueDescriptor* value) const {
1374   // Usage checked by SetRepeatedEnumValue.
1375   USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
1376   SetRepeatedEnumValueInternal(message, field, index, value->number());
1377 }
1378 
SetRepeatedEnumValue(Message * message,const FieldDescriptor * field,int index,int value) const1379 void Reflection::SetRepeatedEnumValue(Message* message,
1380                                       const FieldDescriptor* field, int index,
1381                                       int value) const {
1382   USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
1383   if (!CreateUnknownEnumValues(descriptor_->file())) {
1384     // Check that the value is valid if we don't support direct storage of
1385     // unknown enum values.
1386     const EnumValueDescriptor* value_desc =
1387         field->enum_type()->FindValueByNumber(value);
1388     if (value_desc == nullptr) {
1389       MutableUnknownFields(message)->AddVarint(field->number(), value);
1390       return;
1391     }
1392   }
1393   SetRepeatedEnumValueInternal(message, field, index, value);
1394 }
1395 
SetRepeatedEnumValueInternal(Message * message,const FieldDescriptor * field,int index,int value) const1396 void Reflection::SetRepeatedEnumValueInternal(Message* message,
1397                                               const FieldDescriptor* field,
1398                                               int index, int value) const {
1399   if (field->is_extension()) {
1400     MutableExtensionSet(message)->SetRepeatedEnum(field->number(), index,
1401                                                   value);
1402   } else {
1403     SetRepeatedField<int>(message, field, index, value);
1404   }
1405 }
1406 
AddEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const1407 void Reflection::AddEnum(Message* message, const FieldDescriptor* field,
1408                          const EnumValueDescriptor* value) const {
1409   // Usage checked by AddEnumValue.
1410   USAGE_CHECK_ENUM_VALUE(AddEnum);
1411   AddEnumValueInternal(message, field, value->number());
1412 }
1413 
AddEnumValue(Message * message,const FieldDescriptor * field,int value) const1414 void Reflection::AddEnumValue(Message* message, const FieldDescriptor* field,
1415                               int value) const {
1416   USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
1417   if (!CreateUnknownEnumValues(descriptor_->file())) {
1418     // Check that the value is valid if we don't support direct storage of
1419     // unknown enum values.
1420     const EnumValueDescriptor* value_desc =
1421         field->enum_type()->FindValueByNumber(value);
1422     if (value_desc == nullptr) {
1423       MutableUnknownFields(message)->AddVarint(field->number(), value);
1424       return;
1425     }
1426   }
1427   AddEnumValueInternal(message, field, value);
1428 }
1429 
AddEnumValueInternal(Message * message,const FieldDescriptor * field,int value) const1430 void Reflection::AddEnumValueInternal(Message* message,
1431                                       const FieldDescriptor* field,
1432                                       int value) const {
1433   if (field->is_extension()) {
1434     MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
1435                                           field->options().packed(), value,
1436                                           field);
1437   } else {
1438     AddField<int>(message, field, value);
1439   }
1440 }
1441 
1442 // -------------------------------------------------------------------
1443 
GetMessage(const Message & message,const FieldDescriptor * field,MessageFactory * factory) const1444 const Message& Reflection::GetMessage(const Message& message,
1445                                       const FieldDescriptor* field,
1446                                       MessageFactory* factory) const {
1447   USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
1448 
1449   if (factory == nullptr) factory = message_factory_;
1450 
1451   if (field->is_extension()) {
1452     return static_cast<const Message&>(GetExtensionSet(message).GetMessage(
1453         field->number(), field->message_type(), factory));
1454   } else {
1455     const Message* result = GetRaw<const Message*>(message, field);
1456     if (result == nullptr) {
1457       result = DefaultRaw<const Message*>(field);
1458     }
1459     return *result;
1460   }
1461 }
1462 
MutableMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1463 Message* Reflection::MutableMessage(Message* message,
1464                                     const FieldDescriptor* field,
1465                                     MessageFactory* factory) const {
1466   USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
1467 
1468   if (factory == nullptr) factory = message_factory_;
1469 
1470   if (field->is_extension()) {
1471     return static_cast<Message*>(
1472         MutableExtensionSet(message)->MutableMessage(field, factory));
1473   } else {
1474     Message* result;
1475 
1476     Message** result_holder = MutableRaw<Message*>(message, field);
1477 
1478     if (field->containing_oneof()) {
1479       if (!HasOneofField(*message, field)) {
1480         ClearOneof(message, field->containing_oneof());
1481         result_holder = MutableField<Message*>(message, field);
1482         const Message* default_message = DefaultRaw<const Message*>(field);
1483         *result_holder = default_message->New(message->GetArena());
1484       }
1485     } else {
1486       SetBit(message, field);
1487     }
1488 
1489     if (*result_holder == nullptr) {
1490       const Message* default_message = DefaultRaw<const Message*>(field);
1491       *result_holder = default_message->New(message->GetArena());
1492     }
1493     result = *result_holder;
1494     return result;
1495   }
1496 }
1497 
UnsafeArenaSetAllocatedMessage(Message * message,Message * sub_message,const FieldDescriptor * field) const1498 void Reflection::UnsafeArenaSetAllocatedMessage(
1499     Message* message, Message* sub_message,
1500     const FieldDescriptor* field) const {
1501   USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
1502 
1503   if (field->is_extension()) {
1504     MutableExtensionSet(message)->UnsafeArenaSetAllocatedMessage(
1505         field->number(), field->type(), field, sub_message);
1506   } else {
1507     if (field->containing_oneof()) {
1508       if (sub_message == nullptr) {
1509         ClearOneof(message, field->containing_oneof());
1510         return;
1511       }
1512         ClearOneof(message, field->containing_oneof());
1513         *MutableRaw<Message*>(message, field) = sub_message;
1514       SetOneofCase(message, field);
1515       return;
1516     }
1517 
1518     if (sub_message == nullptr) {
1519       ClearBit(message, field);
1520     } else {
1521       SetBit(message, field);
1522     }
1523     Message** sub_message_holder = MutableRaw<Message*>(message, field);
1524     if (GetArena(message) == nullptr) {
1525       delete *sub_message_holder;
1526     }
1527     *sub_message_holder = sub_message;
1528   }
1529 }
1530 
SetAllocatedMessage(Message * message,Message * sub_message,const FieldDescriptor * field) const1531 void Reflection::SetAllocatedMessage(Message* message, Message* sub_message,
1532                                      const FieldDescriptor* field) const {
1533   // If message and sub-message are in different memory ownership domains
1534   // (different arenas, or one is on heap and one is not), then we may need to
1535   // do a copy.
1536   if (sub_message != nullptr &&
1537       sub_message->GetArena() != message->GetArena()) {
1538     if (sub_message->GetArena() == nullptr && message->GetArena() != nullptr) {
1539       // Case 1: parent is on an arena and child is heap-allocated. We can add
1540       // the child to the arena's Own() list to free on arena destruction, then
1541       // set our pointer.
1542       message->GetArena()->Own(sub_message);
1543       UnsafeArenaSetAllocatedMessage(message, sub_message, field);
1544     } else {
1545       // Case 2: all other cases. We need to make a copy. MutableMessage() will
1546       // either get the existing message object, or instantiate a new one as
1547       // appropriate w.r.t. our arena.
1548       Message* sub_message_copy = MutableMessage(message, field);
1549       sub_message_copy->CopyFrom(*sub_message);
1550     }
1551   } else {
1552     // Same memory ownership domains.
1553     UnsafeArenaSetAllocatedMessage(message, sub_message, field);
1554   }
1555 }
1556 
UnsafeArenaReleaseMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1557 Message* Reflection::UnsafeArenaReleaseMessage(Message* message,
1558                                                const FieldDescriptor* field,
1559                                                MessageFactory* factory) const {
1560   USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
1561 
1562   if (factory == nullptr) factory = message_factory_;
1563 
1564   if (field->is_extension()) {
1565     return static_cast<Message*>(
1566         MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field,
1567                                                                 factory));
1568   } else {
1569     if (!(field->is_repeated() || field->containing_oneof())) {
1570       ClearBit(message, field);
1571     }
1572     if (field->containing_oneof()) {
1573       if (HasOneofField(*message, field)) {
1574         *MutableOneofCase(message, field->containing_oneof()) = 0;
1575       } else {
1576         return nullptr;
1577       }
1578     }
1579     Message** result = MutableRaw<Message*>(message, field);
1580     Message* ret = *result;
1581     *result = nullptr;
1582     return ret;
1583   }
1584 }
1585 
ReleaseMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1586 Message* Reflection::ReleaseMessage(Message* message,
1587                                     const FieldDescriptor* field,
1588                                     MessageFactory* factory) const {
1589   Message* released = UnsafeArenaReleaseMessage(message, field, factory);
1590   if (GetArena(message) != nullptr && released != nullptr) {
1591     Message* copy_from_arena = released->New();
1592     copy_from_arena->CopyFrom(*released);
1593     released = copy_from_arena;
1594   }
1595   return released;
1596 }
1597 
GetRepeatedMessage(const Message & message,const FieldDescriptor * field,int index) const1598 const Message& Reflection::GetRepeatedMessage(const Message& message,
1599                                               const FieldDescriptor* field,
1600                                               int index) const {
1601   USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
1602 
1603   if (field->is_extension()) {
1604     return static_cast<const Message&>(
1605         GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
1606   } else {
1607     if (IsMapFieldInApi(field)) {
1608       return GetRaw<MapFieldBase>(message, field)
1609           .GetRepeatedField()
1610           .Get<GenericTypeHandler<Message> >(index);
1611     } else {
1612       return GetRaw<RepeatedPtrFieldBase>(message, field)
1613           .Get<GenericTypeHandler<Message> >(index);
1614     }
1615   }
1616 }
1617 
MutableRepeatedMessage(Message * message,const FieldDescriptor * field,int index) const1618 Message* Reflection::MutableRepeatedMessage(Message* message,
1619                                             const FieldDescriptor* field,
1620                                             int index) const {
1621   USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
1622 
1623   if (field->is_extension()) {
1624     return static_cast<Message*>(
1625         MutableExtensionSet(message)->MutableRepeatedMessage(field->number(),
1626                                                              index));
1627   } else {
1628     if (IsMapFieldInApi(field)) {
1629       return MutableRaw<MapFieldBase>(message, field)
1630           ->MutableRepeatedField()
1631           ->Mutable<GenericTypeHandler<Message> >(index);
1632     } else {
1633       return MutableRaw<RepeatedPtrFieldBase>(message, field)
1634           ->Mutable<GenericTypeHandler<Message> >(index);
1635     }
1636   }
1637 }
1638 
AddMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const1639 Message* Reflection::AddMessage(Message* message, const FieldDescriptor* field,
1640                                 MessageFactory* factory) const {
1641   USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
1642 
1643   if (factory == nullptr) factory = message_factory_;
1644 
1645   if (field->is_extension()) {
1646     return static_cast<Message*>(
1647         MutableExtensionSet(message)->AddMessage(field, factory));
1648   } else {
1649     Message* result = nullptr;
1650 
1651     // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
1652     // know how to allocate one.
1653     RepeatedPtrFieldBase* repeated = nullptr;
1654     if (IsMapFieldInApi(field)) {
1655       repeated =
1656           MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
1657     } else {
1658       repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
1659     }
1660     result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
1661     if (result == nullptr) {
1662       // We must allocate a new object.
1663       const Message* prototype;
1664       if (repeated->size() == 0) {
1665         prototype = factory->GetPrototype(field->message_type());
1666       } else {
1667         prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
1668       }
1669       result = prototype->New(message->GetArena());
1670       // We can guarantee here that repeated and result are either both heap
1671       // allocated or arena owned. So it is safe to call the unsafe version
1672       // of AddAllocated.
1673       repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message> >(result);
1674     }
1675 
1676     return result;
1677   }
1678 }
1679 
AddAllocatedMessage(Message * message,const FieldDescriptor * field,Message * new_entry) const1680 void Reflection::AddAllocatedMessage(Message* message,
1681                                      const FieldDescriptor* field,
1682                                      Message* new_entry) const {
1683   USAGE_CHECK_ALL(AddAllocatedMessage, REPEATED, MESSAGE);
1684 
1685   if (field->is_extension()) {
1686     MutableExtensionSet(message)->AddAllocatedMessage(field, new_entry);
1687   } else {
1688     RepeatedPtrFieldBase* repeated = nullptr;
1689     if (IsMapFieldInApi(field)) {
1690       repeated =
1691           MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
1692     } else {
1693       repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
1694     }
1695     repeated->AddAllocated<GenericTypeHandler<Message> >(new_entry);
1696   }
1697 }
1698 
MutableRawRepeatedField(Message * message,const FieldDescriptor * field,FieldDescriptor::CppType cpptype,int ctype,const Descriptor * desc) const1699 void* Reflection::MutableRawRepeatedField(Message* message,
1700                                           const FieldDescriptor* field,
1701                                           FieldDescriptor::CppType cpptype,
1702                                           int ctype,
1703                                           const Descriptor* desc) const {
1704   USAGE_CHECK_REPEATED("MutableRawRepeatedField");
1705   if (field->cpp_type() != cpptype &&
1706       (field->cpp_type() != FieldDescriptor::CPPTYPE_ENUM ||
1707        cpptype != FieldDescriptor::CPPTYPE_INT32))
1708     ReportReflectionUsageTypeError(descriptor_, field,
1709                                    "MutableRawRepeatedField", cpptype);
1710   if (desc != nullptr)
1711     GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
1712   if (field->is_extension()) {
1713     return MutableExtensionSet(message)->MutableRawRepeatedField(
1714         field->number(), field->type(), field->is_packed(), field);
1715   } else {
1716     // Trigger transform for MapField
1717     if (IsMapFieldInApi(field)) {
1718       return MutableRawNonOneof<MapFieldBase>(message, field)
1719           ->MutableRepeatedField();
1720     }
1721     return MutableRawNonOneof<void>(message, field);
1722   }
1723 }
1724 
GetRawRepeatedField(const Message & message,const FieldDescriptor * field,FieldDescriptor::CppType cpptype,int ctype,const Descriptor * desc) const1725 const void* Reflection::GetRawRepeatedField(const Message& message,
1726                                             const FieldDescriptor* field,
1727                                             FieldDescriptor::CppType cpptype,
1728                                             int ctype,
1729                                             const Descriptor* desc) const {
1730   USAGE_CHECK_REPEATED("GetRawRepeatedField");
1731   if (field->cpp_type() != cpptype)
1732     ReportReflectionUsageTypeError(descriptor_, field, "GetRawRepeatedField",
1733                                    cpptype);
1734   if (ctype >= 0)
1735     GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
1736   if (desc != nullptr)
1737     GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
1738   if (field->is_extension()) {
1739     // Should use extension_set::GetRawRepeatedField. However, the required
1740     // parameter "default repeated value" is not very easy to get here.
1741     // Map is not supported in extensions, it is acceptable to use
1742     // extension_set::MutableRawRepeatedField which does not change the message.
1743     return MutableExtensionSet(const_cast<Message*>(&message))
1744         ->MutableRawRepeatedField(field->number(), field->type(),
1745                                   field->is_packed(), field);
1746   } else {
1747     // Trigger transform for MapField
1748     if (IsMapFieldInApi(field)) {
1749       return &(GetRawNonOneof<MapFieldBase>(message, field).GetRepeatedField());
1750     }
1751     return &GetRawNonOneof<char>(message, field);
1752   }
1753 }
1754 
GetOneofFieldDescriptor(const Message & message,const OneofDescriptor * oneof_descriptor) const1755 const FieldDescriptor* Reflection::GetOneofFieldDescriptor(
1756     const Message& message, const OneofDescriptor* oneof_descriptor) const {
1757   uint32 field_number = GetOneofCase(message, oneof_descriptor);
1758   if (field_number == 0) {
1759     return nullptr;
1760   }
1761   return descriptor_->FindFieldByNumber(field_number);
1762 }
1763 
ContainsMapKey(const Message & message,const FieldDescriptor * field,const MapKey & key) const1764 bool Reflection::ContainsMapKey(const Message& message,
1765                                 const FieldDescriptor* field,
1766                                 const MapKey& key) const {
1767   USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue",
1768               "Field is not a map field.");
1769   return GetRaw<MapFieldBase>(message, field).ContainsMapKey(key);
1770 }
1771 
InsertOrLookupMapValue(Message * message,const FieldDescriptor * field,const MapKey & key,MapValueRef * val) const1772 bool Reflection::InsertOrLookupMapValue(Message* message,
1773                                         const FieldDescriptor* field,
1774                                         const MapKey& key,
1775                                         MapValueRef* val) const {
1776   USAGE_CHECK(IsMapFieldInApi(field), "InsertOrLookupMapValue",
1777               "Field is not a map field.");
1778   val->SetType(field->message_type()->FindFieldByName("value")->cpp_type());
1779   return MutableRaw<MapFieldBase>(message, field)
1780       ->InsertOrLookupMapValue(key, val);
1781 }
1782 
DeleteMapValue(Message * message,const FieldDescriptor * field,const MapKey & key) const1783 bool Reflection::DeleteMapValue(Message* message, const FieldDescriptor* field,
1784                                 const MapKey& key) const {
1785   USAGE_CHECK(IsMapFieldInApi(field), "DeleteMapValue",
1786               "Field is not a map field.");
1787   return MutableRaw<MapFieldBase>(message, field)->DeleteMapValue(key);
1788 }
1789 
MapBegin(Message * message,const FieldDescriptor * field) const1790 MapIterator Reflection::MapBegin(Message* message,
1791                                  const FieldDescriptor* field) const {
1792   USAGE_CHECK(IsMapFieldInApi(field), "MapBegin", "Field is not a map field.");
1793   MapIterator iter(message, field);
1794   GetRaw<MapFieldBase>(*message, field).MapBegin(&iter);
1795   return iter;
1796 }
1797 
MapEnd(Message * message,const FieldDescriptor * field) const1798 MapIterator Reflection::MapEnd(Message* message,
1799                                const FieldDescriptor* field) const {
1800   USAGE_CHECK(IsMapFieldInApi(field), "MapEnd", "Field is not a map field.");
1801   MapIterator iter(message, field);
1802   GetRaw<MapFieldBase>(*message, field).MapEnd(&iter);
1803   return iter;
1804 }
1805 
MapSize(const Message & message,const FieldDescriptor * field) const1806 int Reflection::MapSize(const Message& message,
1807                         const FieldDescriptor* field) const {
1808   USAGE_CHECK(IsMapFieldInApi(field), "MapSize", "Field is not a map field.");
1809   return GetRaw<MapFieldBase>(message, field).size();
1810 }
1811 
1812 // -----------------------------------------------------------------------------
1813 
FindKnownExtensionByName(const std::string & name) const1814 const FieldDescriptor* Reflection::FindKnownExtensionByName(
1815     const std::string& name) const {
1816   if (!schema_.HasExtensionSet()) return nullptr;
1817   return descriptor_pool_->FindExtensionByPrintableName(descriptor_, name);
1818 }
1819 
FindKnownExtensionByNumber(int number) const1820 const FieldDescriptor* Reflection::FindKnownExtensionByNumber(
1821     int number) const {
1822   if (!schema_.HasExtensionSet()) return nullptr;
1823   return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
1824 }
1825 
SupportsUnknownEnumValues() const1826 bool Reflection::SupportsUnknownEnumValues() const {
1827   return CreateUnknownEnumValues(descriptor_->file());
1828 }
1829 
1830 // ===================================================================
1831 // Some private helpers.
1832 
1833 // These simple template accessors obtain pointers (or references) to
1834 // the given field.
1835 
1836 template <class Type>
GetRawNonOneof(const Message & message,const FieldDescriptor * field) const1837 const Type& Reflection::GetRawNonOneof(const Message& message,
1838                                        const FieldDescriptor* field) const {
1839   return GetConstRefAtOffset<Type>(message,
1840                                    schema_.GetFieldOffsetNonOneof(field));
1841 }
1842 
1843 template <class Type>
MutableRawNonOneof(Message * message,const FieldDescriptor * field) const1844 Type* Reflection::MutableRawNonOneof(Message* message,
1845                                      const FieldDescriptor* field) const {
1846   return GetPointerAtOffset<Type>(message,
1847                                   schema_.GetFieldOffsetNonOneof(field));
1848 }
1849 
1850 template <typename Type>
GetRaw(const Message & message,const FieldDescriptor * field) const1851 const Type& Reflection::GetRaw(const Message& message,
1852                                const FieldDescriptor* field) const {
1853   if (field->containing_oneof() && !HasOneofField(message, field)) {
1854     return DefaultRaw<Type>(field);
1855   }
1856   return GetConstRefAtOffset<Type>(message, schema_.GetFieldOffset(field));
1857 }
1858 
IsInlined(const FieldDescriptor * field) const1859 bool Reflection::IsInlined(const FieldDescriptor* field) const {
1860   return schema_.IsFieldInlined(field);
1861 }
1862 
1863 template <typename Type>
MutableRaw(Message * message,const FieldDescriptor * field) const1864 Type* Reflection::MutableRaw(Message* message,
1865                              const FieldDescriptor* field) const {
1866   return GetPointerAtOffset<Type>(message, schema_.GetFieldOffset(field));
1867 }
1868 
GetHasBits(const Message & message) const1869 const uint32* Reflection::GetHasBits(const Message& message) const {
1870   GOOGLE_DCHECK(schema_.HasHasbits());
1871   return &GetConstRefAtOffset<uint32>(message, schema_.HasBitsOffset());
1872 }
1873 
MutableHasBits(Message * message) const1874 uint32* Reflection::MutableHasBits(Message* message) const {
1875   GOOGLE_DCHECK(schema_.HasHasbits());
1876   return GetPointerAtOffset<uint32>(message, schema_.HasBitsOffset());
1877 }
1878 
GetOneofCase(const Message & message,const OneofDescriptor * oneof_descriptor) const1879 uint32 Reflection::GetOneofCase(const Message& message,
1880                                 const OneofDescriptor* oneof_descriptor) const {
1881   return GetConstRefAtOffset<uint32>(
1882       message, schema_.GetOneofCaseOffset(oneof_descriptor));
1883 }
1884 
MutableOneofCase(Message * message,const OneofDescriptor * oneof_descriptor) const1885 uint32* Reflection::MutableOneofCase(
1886     Message* message, const OneofDescriptor* oneof_descriptor) const {
1887   return GetPointerAtOffset<uint32>(
1888       message, schema_.GetOneofCaseOffset(oneof_descriptor));
1889 }
1890 
GetExtensionSet(const Message & message) const1891 const ExtensionSet& Reflection::GetExtensionSet(const Message& message) const {
1892   return GetConstRefAtOffset<ExtensionSet>(message,
1893                                            schema_.GetExtensionSetOffset());
1894 }
1895 
MutableExtensionSet(Message * message) const1896 ExtensionSet* Reflection::MutableExtensionSet(Message* message) const {
1897   return GetPointerAtOffset<ExtensionSet>(message,
1898                                           schema_.GetExtensionSetOffset());
1899 }
1900 
GetArena(Message * message) const1901 Arena* Reflection::GetArena(Message* message) const {
1902   return GetInternalMetadataWithArena(*message).arena();
1903 }
1904 
GetInternalMetadataWithArena(const Message & message) const1905 const InternalMetadataWithArena& Reflection::GetInternalMetadataWithArena(
1906     const Message& message) const {
1907   return GetConstRefAtOffset<InternalMetadataWithArena>(
1908       message, schema_.GetMetadataOffset());
1909 }
1910 
MutableInternalMetadataWithArena(Message * message) const1911 InternalMetadataWithArena* Reflection::MutableInternalMetadataWithArena(
1912     Message* message) const {
1913   return GetPointerAtOffset<InternalMetadataWithArena>(
1914       message, schema_.GetMetadataOffset());
1915 }
1916 
1917 template <typename Type>
DefaultRaw(const FieldDescriptor * field) const1918 const Type& Reflection::DefaultRaw(const FieldDescriptor* field) const {
1919   return *reinterpret_cast<const Type*>(schema_.GetFieldDefault(field));
1920 }
1921 
1922 // Simple accessors for manipulating has_bits_.
HasBit(const Message & message,const FieldDescriptor * field) const1923 bool Reflection::HasBit(const Message& message,
1924                         const FieldDescriptor* field) const {
1925   GOOGLE_DCHECK(!field->options().weak());
1926   if (schema_.HasHasbits()) {
1927     return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field));
1928   }
1929 
1930   // proto3: no has-bits. All fields present except messages, which are
1931   // present only if their message-field pointer is non-null.
1932   if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1933     return !schema_.IsDefaultInstance(message) &&
1934            GetRaw<const Message*>(message, field) != nullptr;
1935   } else {
1936     // Non-message field (and non-oneof, since that was handled in HasField()
1937     // before calling us), and singular (again, checked in HasField). So, this
1938     // field must be a scalar.
1939 
1940     // Scalar primitive (numeric or string/bytes) fields are present if
1941     // their value is non-zero (numeric) or non-empty (string/bytes). N.B.:
1942     // we must use this definition here, rather than the "scalar fields
1943     // always present" in the proto3 docs, because MergeFrom() semantics
1944     // require presence as "present on wire", and reflection-based merge
1945     // (which uses HasField()) needs to be consistent with this.
1946     switch (field->cpp_type()) {
1947       case FieldDescriptor::CPPTYPE_STRING:
1948         switch (field->options().ctype()) {
1949           default: {
1950             if (IsInlined(field)) {
1951               return !GetField<InlinedStringField>(message, field)
1952                           .GetNoArena()
1953                           .empty();
1954             }
1955             return GetField<ArenaStringPtr>(message, field).Get().size() > 0;
1956           }
1957         }
1958         return false;
1959       case FieldDescriptor::CPPTYPE_BOOL:
1960         return GetRaw<bool>(message, field) != false;
1961       case FieldDescriptor::CPPTYPE_INT32:
1962         return GetRaw<int32>(message, field) != 0;
1963       case FieldDescriptor::CPPTYPE_INT64:
1964         return GetRaw<int64>(message, field) != 0;
1965       case FieldDescriptor::CPPTYPE_UINT32:
1966         return GetRaw<uint32>(message, field) != 0;
1967       case FieldDescriptor::CPPTYPE_UINT64:
1968         return GetRaw<uint64>(message, field) != 0;
1969       case FieldDescriptor::CPPTYPE_FLOAT:
1970         return GetRaw<float>(message, field) != 0.0;
1971       case FieldDescriptor::CPPTYPE_DOUBLE:
1972         return GetRaw<double>(message, field) != 0.0;
1973       case FieldDescriptor::CPPTYPE_ENUM:
1974         return GetRaw<int>(message, field) != 0;
1975       case FieldDescriptor::CPPTYPE_MESSAGE:
1976         // handled above; avoid warning
1977         break;
1978     }
1979     GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit().";
1980     return false;
1981   }
1982 }
1983 
SetBit(Message * message,const FieldDescriptor * field) const1984 void Reflection::SetBit(Message* message, const FieldDescriptor* field) const {
1985   GOOGLE_DCHECK(!field->options().weak());
1986   if (!schema_.HasHasbits()) {
1987     return;
1988   }
1989   const uint32 index = schema_.HasBitIndex(field);
1990   MutableHasBits(message)[index / 32] |=
1991       (static_cast<uint32>(1) << (index % 32));
1992 }
1993 
ClearBit(Message * message,const FieldDescriptor * field) const1994 void Reflection::ClearBit(Message* message,
1995                           const FieldDescriptor* field) const {
1996   GOOGLE_DCHECK(!field->options().weak());
1997   if (!schema_.HasHasbits()) {
1998     return;
1999   }
2000   const uint32 index = schema_.HasBitIndex(field);
2001   MutableHasBits(message)[index / 32] &=
2002       ~(static_cast<uint32>(1) << (index % 32));
2003 }
2004 
SwapBit(Message * message1,Message * message2,const FieldDescriptor * field) const2005 void Reflection::SwapBit(Message* message1, Message* message2,
2006                          const FieldDescriptor* field) const {
2007   GOOGLE_DCHECK(!field->options().weak());
2008   if (!schema_.HasHasbits()) {
2009     return;
2010   }
2011   bool temp_has_bit = HasBit(*message1, field);
2012   if (HasBit(*message2, field)) {
2013     SetBit(message1, field);
2014   } else {
2015     ClearBit(message1, field);
2016   }
2017   if (temp_has_bit) {
2018     SetBit(message2, field);
2019   } else {
2020     ClearBit(message2, field);
2021   }
2022 }
2023 
HasOneof(const Message & message,const OneofDescriptor * oneof_descriptor) const2024 bool Reflection::HasOneof(const Message& message,
2025                           const OneofDescriptor* oneof_descriptor) const {
2026   return (GetOneofCase(message, oneof_descriptor) > 0);
2027 }
2028 
HasOneofField(const Message & message,const FieldDescriptor * field) const2029 bool Reflection::HasOneofField(const Message& message,
2030                                const FieldDescriptor* field) const {
2031   return (GetOneofCase(message, field->containing_oneof()) == field->number());
2032 }
2033 
SetOneofCase(Message * message,const FieldDescriptor * field) const2034 void Reflection::SetOneofCase(Message* message,
2035                               const FieldDescriptor* field) const {
2036   *MutableOneofCase(message, field->containing_oneof()) = field->number();
2037 }
2038 
ClearOneofField(Message * message,const FieldDescriptor * field) const2039 void Reflection::ClearOneofField(Message* message,
2040                                  const FieldDescriptor* field) const {
2041   if (HasOneofField(*message, field)) {
2042     ClearOneof(message, field->containing_oneof());
2043   }
2044 }
2045 
ClearOneof(Message * message,const OneofDescriptor * oneof_descriptor) const2046 void Reflection::ClearOneof(Message* message,
2047                             const OneofDescriptor* oneof_descriptor) const {
2048   // TODO(jieluo): Consider to cache the unused object instead of deleting
2049   // it. It will be much faster if an application switches a lot from
2050   // a few oneof fields.  Time/space tradeoff
2051   uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
2052   if (oneof_case > 0) {
2053     const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
2054     if (GetArena(message) == nullptr) {
2055       switch (field->cpp_type()) {
2056         case FieldDescriptor::CPPTYPE_STRING: {
2057           switch (field->options().ctype()) {
2058             default:  // TODO(kenton):  Support other string reps.
2059             case FieldOptions::STRING: {
2060               const std::string* default_ptr =
2061                   &DefaultRaw<ArenaStringPtr>(field).Get();
2062               MutableField<ArenaStringPtr>(message, field)
2063                   ->Destroy(default_ptr, GetArena(message));
2064               break;
2065             }
2066           }
2067           break;
2068         }
2069 
2070         case FieldDescriptor::CPPTYPE_MESSAGE:
2071           delete *MutableRaw<Message*>(message, field);
2072           break;
2073         default:
2074           break;
2075       }
2076     }
2077 
2078     *MutableOneofCase(message, oneof_descriptor) = 0;
2079   }
2080 }
2081 
2082 #define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE)                                \
2083   template <>                                                            \
2084   const RepeatedField<TYPE>& Reflection::GetRepeatedFieldInternal<TYPE>( \
2085       const Message& message, const FieldDescriptor* field) const {      \
2086     return *static_cast<RepeatedField<TYPE>*>(MutableRawRepeatedField(   \
2087         const_cast<Message*>(&message), field, CPPTYPE, CTYPE, NULL));   \
2088   }                                                                      \
2089                                                                          \
2090   template <>                                                            \
2091   RepeatedField<TYPE>* Reflection::MutableRepeatedFieldInternal<TYPE>(   \
2092       Message * message, const FieldDescriptor* field) const {           \
2093     return static_cast<RepeatedField<TYPE>*>(                            \
2094         MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL));  \
2095   }
2096 
2097 HANDLE_TYPE(int32, FieldDescriptor::CPPTYPE_INT32, -1);
2098 HANDLE_TYPE(int64, FieldDescriptor::CPPTYPE_INT64, -1);
2099 HANDLE_TYPE(uint32, FieldDescriptor::CPPTYPE_UINT32, -1);
2100 HANDLE_TYPE(uint64, FieldDescriptor::CPPTYPE_UINT64, -1);
2101 HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1);
2102 HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1);
2103 HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1);
2104 
2105 
2106 #undef HANDLE_TYPE
2107 
MutableRawRepeatedString(Message * message,const FieldDescriptor * field,bool is_string) const2108 void* Reflection::MutableRawRepeatedString(Message* message,
2109                                            const FieldDescriptor* field,
2110                                            bool is_string) const {
2111   return MutableRawRepeatedField(message, field,
2112                                  FieldDescriptor::CPPTYPE_STRING,
2113                                  FieldOptions::STRING, NULL);
2114 }
2115 
2116 // Template implementations of basic accessors.  Inline because each
2117 // template instance is only called from one location.  These are
2118 // used for all types except messages.
2119 template <typename Type>
GetField(const Message & message,const FieldDescriptor * field) const2120 const Type& Reflection::GetField(const Message& message,
2121                                  const FieldDescriptor* field) const {
2122   return GetRaw<Type>(message, field);
2123 }
2124 
2125 template <typename Type>
SetField(Message * message,const FieldDescriptor * field,const Type & value) const2126 void Reflection::SetField(Message* message, const FieldDescriptor* field,
2127                           const Type& value) const {
2128   if (field->containing_oneof() && !HasOneofField(*message, field)) {
2129     ClearOneof(message, field->containing_oneof());
2130   }
2131   *MutableRaw<Type>(message, field) = value;
2132   field->containing_oneof() ? SetOneofCase(message, field)
2133                             : SetBit(message, field);
2134 }
2135 
2136 template <typename Type>
MutableField(Message * message,const FieldDescriptor * field) const2137 Type* Reflection::MutableField(Message* message,
2138                                const FieldDescriptor* field) const {
2139   field->containing_oneof() ? SetOneofCase(message, field)
2140                             : SetBit(message, field);
2141   return MutableRaw<Type>(message, field);
2142 }
2143 
2144 template <typename Type>
GetRepeatedField(const Message & message,const FieldDescriptor * field,int index) const2145 const Type& Reflection::GetRepeatedField(const Message& message,
2146                                          const FieldDescriptor* field,
2147                                          int index) const {
2148   return GetRaw<RepeatedField<Type> >(message, field).Get(index);
2149 }
2150 
2151 template <typename Type>
GetRepeatedPtrField(const Message & message,const FieldDescriptor * field,int index) const2152 const Type& Reflection::GetRepeatedPtrField(const Message& message,
2153                                             const FieldDescriptor* field,
2154                                             int index) const {
2155   return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
2156 }
2157 
2158 template <typename Type>
SetRepeatedField(Message * message,const FieldDescriptor * field,int index,Type value) const2159 void Reflection::SetRepeatedField(Message* message,
2160                                   const FieldDescriptor* field, int index,
2161                                   Type value) const {
2162   MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
2163 }
2164 
2165 template <typename Type>
MutableRepeatedField(Message * message,const FieldDescriptor * field,int index) const2166 Type* Reflection::MutableRepeatedField(Message* message,
2167                                        const FieldDescriptor* field,
2168                                        int index) const {
2169   RepeatedPtrField<Type>* repeated =
2170       MutableRaw<RepeatedPtrField<Type> >(message, field);
2171   return repeated->Mutable(index);
2172 }
2173 
2174 template <typename Type>
AddField(Message * message,const FieldDescriptor * field,const Type & value) const2175 void Reflection::AddField(Message* message, const FieldDescriptor* field,
2176                           const Type& value) const {
2177   MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
2178 }
2179 
2180 template <typename Type>
AddField(Message * message,const FieldDescriptor * field) const2181 Type* Reflection::AddField(Message* message,
2182                            const FieldDescriptor* field) const {
2183   RepeatedPtrField<Type>* repeated =
2184       MutableRaw<RepeatedPtrField<Type> >(message, field);
2185   return repeated->Add();
2186 }
2187 
GetMessageFactory() const2188 MessageFactory* Reflection::GetMessageFactory() const {
2189   return message_factory_;
2190 }
2191 
RepeatedFieldData(Message * message,const FieldDescriptor * field,FieldDescriptor::CppType cpp_type,const Descriptor * message_type) const2192 void* Reflection::RepeatedFieldData(Message* message,
2193                                     const FieldDescriptor* field,
2194                                     FieldDescriptor::CppType cpp_type,
2195                                     const Descriptor* message_type) const {
2196   GOOGLE_CHECK(field->is_repeated());
2197   GOOGLE_CHECK(field->cpp_type() == cpp_type ||
2198         (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
2199          cpp_type == FieldDescriptor::CPPTYPE_INT32))
2200       << "The type parameter T in RepeatedFieldRef<T> API doesn't match "
2201       << "the actual field type (for enums T should be the generated enum "
2202       << "type or int32).";
2203   if (message_type != nullptr) {
2204     GOOGLE_CHECK_EQ(message_type, field->message_type());
2205   }
2206   if (field->is_extension()) {
2207     return MutableExtensionSet(message)->MutableRawRepeatedField(
2208         field->number(), field->type(), field->is_packed(), field);
2209   } else {
2210     return MutableRawNonOneof<char>(message, field);
2211   }
2212 }
2213 
MutableMapData(Message * message,const FieldDescriptor * field) const2214 MapFieldBase* Reflection::MutableMapData(Message* message,
2215                                          const FieldDescriptor* field) const {
2216   USAGE_CHECK(IsMapFieldInApi(field), "GetMapData",
2217               "Field is not a map field.");
2218   return MutableRaw<MapFieldBase>(message, field);
2219 }
2220 
GetMapData(const Message & message,const FieldDescriptor * field) const2221 const MapFieldBase* Reflection::GetMapData(const Message& message,
2222                                            const FieldDescriptor* field) const {
2223   USAGE_CHECK(IsMapFieldInApi(field), "GetMapData",
2224               "Field is not a map field.");
2225   return &(GetRaw<MapFieldBase>(message, field));
2226 }
2227 
2228 namespace {
2229 
2230 // Helper function to transform migration schema into reflection schema.
MigrationToReflectionSchema(const Message * const * default_instance,const uint32 * offsets,MigrationSchema migration_schema)2231 ReflectionSchema MigrationToReflectionSchema(
2232     const Message* const* default_instance, const uint32* offsets,
2233     MigrationSchema migration_schema) {
2234   ReflectionSchema result;
2235   result.default_instance_ = *default_instance;
2236   // First 6 offsets are offsets to the special fields. The following offsets
2237   // are the proto fields.
2238   result.offsets_ = offsets + migration_schema.offsets_index + 5;
2239   result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index;
2240   result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0];
2241   result.metadata_offset_ = offsets[migration_schema.offsets_index + 1];
2242   result.extensions_offset_ = offsets[migration_schema.offsets_index + 2];
2243   result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3];
2244   result.object_size_ = migration_schema.object_size;
2245   result.weak_field_map_offset_ = offsets[migration_schema.offsets_index + 4];
2246   return result;
2247 }
2248 
2249 }  // namespace
2250 
2251 class AssignDescriptorsHelper {
2252  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)2253   AssignDescriptorsHelper(MessageFactory* factory,
2254                           Metadata* file_level_metadata,
2255                           const EnumDescriptor** file_level_enum_descriptors,
2256                           const MigrationSchema* schemas,
2257                           const Message* const* default_instance_data,
2258                           const uint32* offsets)
2259       : factory_(factory),
2260         file_level_metadata_(file_level_metadata),
2261         file_level_enum_descriptors_(file_level_enum_descriptors),
2262         schemas_(schemas),
2263         default_instance_data_(default_instance_data),
2264         offsets_(offsets) {}
2265 
AssignMessageDescriptor(const Descriptor * descriptor)2266   void AssignMessageDescriptor(const Descriptor* descriptor) {
2267     for (int i = 0; i < descriptor->nested_type_count(); i++) {
2268       AssignMessageDescriptor(descriptor->nested_type(i));
2269     }
2270 
2271     file_level_metadata_->descriptor = descriptor;
2272 
2273     file_level_metadata_->reflection =
2274         new Reflection(descriptor,
2275                        MigrationToReflectionSchema(default_instance_data_,
2276                                                    offsets_, *schemas_),
2277                        DescriptorPool::internal_generated_pool(), factory_);
2278     for (int i = 0; i < descriptor->enum_type_count(); i++) {
2279       AssignEnumDescriptor(descriptor->enum_type(i));
2280     }
2281     schemas_++;
2282     default_instance_data_++;
2283     file_level_metadata_++;
2284   }
2285 
AssignEnumDescriptor(const EnumDescriptor * descriptor)2286   void AssignEnumDescriptor(const EnumDescriptor* descriptor) {
2287     *file_level_enum_descriptors_ = descriptor;
2288     file_level_enum_descriptors_++;
2289   }
2290 
GetCurrentMetadataPtr() const2291   const Metadata* GetCurrentMetadataPtr() const { return file_level_metadata_; }
2292 
2293  private:
2294   MessageFactory* factory_;
2295   Metadata* file_level_metadata_;
2296   const EnumDescriptor** file_level_enum_descriptors_;
2297   const MigrationSchema* schemas_;
2298   const Message* const* default_instance_data_;
2299   const uint32* offsets_;
2300 };
2301 
2302 namespace {
2303 
2304 // We have the routines that assign descriptors and build reflection
2305 // automatically delete the allocated reflection. MetadataOwner owns
2306 // all the allocated reflection instances.
2307 struct MetadataOwner {
~MetadataOwnergoogle::protobuf::__anonf2ed1b540511::MetadataOwner2308   ~MetadataOwner() {
2309     for (auto range : metadata_arrays_) {
2310       for (const Metadata* m = range.first; m < range.second; m++) {
2311         delete m->reflection;
2312       }
2313     }
2314   }
2315 
AddArraygoogle::protobuf::__anonf2ed1b540511::MetadataOwner2316   void AddArray(const Metadata* begin, const Metadata* end) {
2317     mu_.Lock();
2318     metadata_arrays_.push_back(std::make_pair(begin, end));
2319     mu_.Unlock();
2320   }
2321 
Instancegoogle::protobuf::__anonf2ed1b540511::MetadataOwner2322   static MetadataOwner* Instance() {
2323     static MetadataOwner* res = OnShutdownDelete(new MetadataOwner);
2324     return res;
2325   }
2326 
2327  private:
2328   MetadataOwner() = default;  // private because singleton
2329 
2330   WrappedMutex mu_;
2331   std::vector<std::pair<const Metadata*, const Metadata*> > metadata_arrays_;
2332 };
2333 
AssignDescriptorsImpl(const DescriptorTable * table)2334 void AssignDescriptorsImpl(const DescriptorTable* table) {
2335   // Ensure the file descriptor is added to the pool.
2336   {
2337     // This only happens once per proto file. So a global mutex to serialize
2338     // calls to AddDescriptors.
2339     static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED};
2340     mu.Lock();
2341     AddDescriptors(table);
2342     mu.Unlock();
2343   }
2344   // Fill the arrays with pointers to descriptors and reflection classes.
2345   const FileDescriptor* file =
2346       DescriptorPool::internal_generated_pool()->FindFileByName(
2347           table->filename);
2348   GOOGLE_CHECK(file != nullptr);
2349 
2350   MessageFactory* factory = MessageFactory::generated_factory();
2351 
2352   AssignDescriptorsHelper helper(
2353       factory, table->file_level_metadata, table->file_level_enum_descriptors,
2354       table->schemas, table->default_instances, table->offsets);
2355 
2356   for (int i = 0; i < file->message_type_count(); i++) {
2357     helper.AssignMessageDescriptor(file->message_type(i));
2358   }
2359 
2360   for (int i = 0; i < file->enum_type_count(); i++) {
2361     helper.AssignEnumDescriptor(file->enum_type(i));
2362   }
2363   if (file->options().cc_generic_services()) {
2364     for (int i = 0; i < file->service_count(); i++) {
2365       table->file_level_service_descriptors[i] = file->service(i);
2366     }
2367   }
2368   MetadataOwner::Instance()->AddArray(table->file_level_metadata,
2369                                       helper.GetCurrentMetadataPtr());
2370 }
2371 
AddDescriptorsImpl(const DescriptorTable * table)2372 void AddDescriptorsImpl(const DescriptorTable* table) {
2373   // Reflection refers to the default instances so make sure they are
2374   // initialized.
2375   for (int i = 0; i < table->num_sccs; i++) {
2376     internal::InitSCC(table->init_default_instances[i]);
2377   }
2378 
2379   // Ensure all dependent descriptors are registered to the generated descriptor
2380   // pool and message factory.
2381   for (int i = 0; i < table->num_deps; i++) {
2382     // In case of weak fields deps[i] could be null.
2383     if (table->deps[i]) AddDescriptors(table->deps[i]);
2384   }
2385 
2386   // Register the descriptor of this file.
2387   DescriptorPool::InternalAddGeneratedFile(table->descriptor, table->size);
2388   MessageFactory::InternalRegisterGeneratedFile(table);
2389 }
2390 
2391 }  // namespace
2392 
2393 // Separate function because it needs to be a friend of
2394 // Reflection
RegisterAllTypesInternal(const Metadata * file_level_metadata,int size)2395 void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) {
2396   for (int i = 0; i < size; i++) {
2397     const Reflection* reflection = file_level_metadata[i].reflection;
2398     MessageFactory::InternalRegisterGeneratedMessage(
2399         file_level_metadata[i].descriptor,
2400         reflection->schema_.default_instance_);
2401   }
2402 }
2403 
2404 namespace internal {
2405 
AssignDescriptors(const DescriptorTable * table)2406 void AssignDescriptors(const DescriptorTable* table) {
2407   call_once(*table->once, AssignDescriptorsImpl, table);
2408 }
2409 
AddDescriptors(const DescriptorTable * table)2410 void AddDescriptors(const DescriptorTable* table) {
2411   // AddDescriptors is not thread safe. Callers need to ensure calls are
2412   // properly serialized. This function is only called pre-main by global
2413   // descriptors and we can assume single threaded access or it's called
2414   // by AssignDescriptorImpl which uses a mutex to sequence calls.
2415   if (*table->is_initialized) return;
2416   *table->is_initialized = true;
2417   AddDescriptorsImpl(table);
2418 }
2419 
RegisterFileLevelMetadata(const DescriptorTable * table)2420 void RegisterFileLevelMetadata(const DescriptorTable* table) {
2421   AssignDescriptors(table);
2422   RegisterAllTypesInternal(table->file_level_metadata, table->num_messages);
2423 }
2424 
UnknownFieldSetSerializer(const uint8 * base,uint32 offset,uint32 tag,uint32 has_offset,io::CodedOutputStream * output)2425 void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag,
2426                                uint32 has_offset,
2427                                io::CodedOutputStream* output) {
2428   const void* ptr = base + offset;
2429   const InternalMetadataWithArena* metadata =
2430       static_cast<const InternalMetadataWithArena*>(ptr);
2431   if (metadata->have_unknown_fields()) {
2432     internal::WireFormat::SerializeUnknownFields(metadata->unknown_fields(),
2433                                                  output);
2434   }
2435 }
2436 
2437 }  // namespace internal
2438 }  // namespace protobuf
2439 }  // namespace google
2440