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