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