• 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/stubs/mutex.h>
43 #include <google/protobuf/stubs/casts.h>
44 #include <google/protobuf/stubs/strutil.h>
45 #include <google/protobuf/descriptor.h>
46 #include <google/protobuf/descriptor.pb.h>
47 #include <google/protobuf/extension_set.h>
48 #include <google/protobuf/generated_message_util.h>
49 #include <google/protobuf/inlined_string_field.h>
50 #include <google/protobuf/map_field.h>
51 #include <google/protobuf/map_field_inl.h>
52 #include <google/protobuf/repeated_field.h>
53 #include <google/protobuf/unknown_field_set.h>
54 
55 
56 // clang-format off
57 #include <google/protobuf/port_def.inc>
58 // clang-format on
59 
60 #define GOOGLE_PROTOBUF_HAS_ONEOF
61 
62 using google::protobuf::internal::ArenaStringPtr;
63 using google::protobuf::internal::DescriptorTable;
64 using google::protobuf::internal::ExtensionSet;
65 using google::protobuf::internal::GenericTypeHandler;
66 using google::protobuf::internal::GetEmptyString;
67 using google::protobuf::internal::InlinedStringField;
68 using google::protobuf::internal::InternalMetadata;
69 using google::protobuf::internal::LazyField;
70 using google::protobuf::internal::MapFieldBase;
71 using google::protobuf::internal::MigrationSchema;
72 using google::protobuf::internal::OnShutdownDelete;
73 using google::protobuf::internal::ReflectionSchema;
74 using google::protobuf::internal::RepeatedPtrFieldBase;
75 using google::protobuf::internal::StringSpaceUsedExcludingSelfLong;
76 using google::protobuf::internal::WrappedMutex;
77 
78 namespace google {
79 namespace protobuf {
80 
81 namespace {
IsMapFieldInApi(const FieldDescriptor * field)82 bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); }
83 
84 #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
MaybeForceCopy(Arena * arena,Message * msg)85 Message* MaybeForceCopy(Arena* arena, Message* msg) {
86   if (arena != nullptr || msg == nullptr) return msg;
87 
88   Message* copy = msg->New();
89   copy->MergeFrom(*msg);
90   delete msg;
91   return copy;
92 }
93 #endif  // PROTOBUF_FORCE_COPY_IN_RELEASE
94 }  // anonymous namespace
95 
96 namespace internal {
97 
ParseNamedEnum(const EnumDescriptor * descriptor,ConstStringParam name,int * value)98 bool ParseNamedEnum(const EnumDescriptor* descriptor, ConstStringParam name,
99                     int* value) {
100   const EnumValueDescriptor* d = descriptor->FindValueByName(name);
101   if (d == nullptr) return false;
102   *value = d->number();
103   return true;
104 }
105 
NameOfEnum(const EnumDescriptor * descriptor,int value)106 const std::string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
107   const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
108   return (d == nullptr ? GetEmptyString() : d->name());
109 }
110 
111 }  // namespace internal
112 
113 // ===================================================================
114 // Helpers for reporting usage errors (e.g. trying to use GetInt32() on
115 // a string field).
116 
117 namespace {
118 
119 using internal::GetConstPointerAtOffset;
120 using internal::GetConstRefAtOffset;
121 using internal::GetPointerAtOffset;
122 
ReportReflectionUsageError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,const char * description)123 void ReportReflectionUsageError(const Descriptor* descriptor,
124                                 const FieldDescriptor* field,
125                                 const char* method, const char* description) {
126   GOOGLE_LOG(FATAL) << "Protocol Buffer reflection usage error:\n"
127                 "  Method      : google::protobuf::Reflection::"
128              << method
129              << "\n"
130                 "  Message type: "
131              << descriptor->full_name()
132              << "\n"
133                 "  Field       : "
134              << field->full_name()
135              << "\n"
136                 "  Problem     : "
137              << description;
138 }
139 
140 const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = {
141     "INVALID_CPPTYPE", "CPPTYPE_INT32",  "CPPTYPE_INT64",  "CPPTYPE_UINT32",
142     "CPPTYPE_UINT64",  "CPPTYPE_DOUBLE", "CPPTYPE_FLOAT",  "CPPTYPE_BOOL",
143     "CPPTYPE_ENUM",    "CPPTYPE_STRING", "CPPTYPE_MESSAGE"};
144 
ReportReflectionUsageTypeError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,FieldDescriptor::CppType expected_type)145 static void ReportReflectionUsageTypeError(
146     const Descriptor* descriptor, const FieldDescriptor* field,
147     const char* method, FieldDescriptor::CppType expected_type) {
148   GOOGLE_LOG(FATAL)
149       << "Protocol Buffer reflection usage error:\n"
150          "  Method      : google::protobuf::Reflection::"
151       << method
152       << "\n"
153          "  Message type: "
154       << descriptor->full_name()
155       << "\n"
156          "  Field       : "
157       << field->full_name()
158       << "\n"
159          "  Problem     : Field is not the right type for this message:\n"
160          "    Expected  : "
161       << cpptype_names_[expected_type]
162       << "\n"
163          "    Field type: "
164       << cpptype_names_[field->cpp_type()];
165 }
166 
ReportReflectionUsageEnumTypeError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,const EnumValueDescriptor * value)167 static void ReportReflectionUsageEnumTypeError(
168     const Descriptor* descriptor, const FieldDescriptor* field,
169     const char* method, const EnumValueDescriptor* value) {
170   GOOGLE_LOG(FATAL) << "Protocol Buffer reflection usage error:\n"
171                 "  Method      : google::protobuf::Reflection::"
172              << method
173              << "\n"
174                 "  Message type: "
175              << descriptor->full_name()
176              << "\n"
177                 "  Field       : "
178              << field->full_name()
179              << "\n"
180                 "  Problem     : Enum value did not match field type:\n"
181                 "    Expected  : "
182              << field->enum_type()->full_name()
183              << "\n"
184                 "    Actual    : "
185              << value->full_name();
186 }
187 
CheckInvalidAccess(const internal::ReflectionSchema & schema,const FieldDescriptor * field)188 inline void CheckInvalidAccess(const internal::ReflectionSchema& schema,
189                                const FieldDescriptor* field) {
190   GOOGLE_CHECK(!schema.IsFieldStripped(field))
191       << "invalid access to a stripped field " << field->full_name();
192 }
193 
194 #define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \
195   if (!(CONDITION))                                       \
196   ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION)
197 #define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \
198   USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION)
199 #define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \
200   USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION)
201 
202 #define USAGE_CHECK_TYPE(METHOD, CPPTYPE)                      \
203   if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \
204   ReportReflectionUsageTypeError(descriptor_, field, #METHOD,  \
205                                  FieldDescriptor::CPPTYPE_##CPPTYPE)
206 
207 #define USAGE_CHECK_ENUM_VALUE(METHOD)     \
208   if (value->type() != field->enum_type()) \
209   ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value)
210 
211 #define USAGE_CHECK_MESSAGE_TYPE(METHOD)                        \
212   USAGE_CHECK_EQ(field->containing_type(), descriptor_, METHOD, \
213                  "Field does not match message type.");
214 #define USAGE_CHECK_SINGULAR(METHOD)                                      \
215   USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
216                  "Field is repeated; the method requires a singular field.")
217 #define USAGE_CHECK_REPEATED(METHOD)                                      \
218   USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
219                  "Field is singular; the method requires a repeated field.")
220 
221 #define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \
222   USAGE_CHECK_MESSAGE_TYPE(METHOD);             \
223   USAGE_CHECK_##LABEL(METHOD);                  \
224   USAGE_CHECK_TYPE(METHOD, CPPTYPE)
225 
226 }  // namespace
227 
228 // ===================================================================
229 
Reflection(const Descriptor * descriptor,const internal::ReflectionSchema & schema,const DescriptorPool * pool,MessageFactory * factory)230 Reflection::Reflection(const Descriptor* descriptor,
231                        const internal::ReflectionSchema& schema,
232                        const DescriptorPool* pool, MessageFactory* factory)
233     : descriptor_(descriptor),
234       schema_(schema),
235       descriptor_pool_(
236           (pool == nullptr) ? DescriptorPool::internal_generated_pool() : pool),
237       message_factory_(factory),
238       last_non_weak_field_index_(-1) {
239   last_non_weak_field_index_ = descriptor_->field_count() - 1;
240 }
241 
GetUnknownFields(const Message & message) const242 const UnknownFieldSet& Reflection::GetUnknownFields(
243     const Message& message) const {
244   return GetInternalMetadata(message).unknown_fields<UnknownFieldSet>(
245       UnknownFieldSet::default_instance);
246 }
247 
MutableUnknownFields(Message * message) const248 UnknownFieldSet* Reflection::MutableUnknownFields(Message* message) const {
249   return MutableInternalMetadata(message)
250       ->mutable_unknown_fields<UnknownFieldSet>();
251 }
252 
IsLazyExtension(const Message & message,const FieldDescriptor * field) const253 bool Reflection::IsLazyExtension(const Message& message,
254                                  const FieldDescriptor* field) const {
255   return field->is_extension() &&
256          GetExtensionSet(message).HasLazy(field->number());
257 }
258 
IsLazilyVerifiedLazyField(const FieldDescriptor * field) const259 bool Reflection::IsLazilyVerifiedLazyField(const FieldDescriptor* field) const {
260   return field->options().lazy() || field->options().unverified_lazy();
261 }
262 
IsEagerlyVerifiedLazyField(const FieldDescriptor * field) const263 bool Reflection::IsEagerlyVerifiedLazyField(
264     const FieldDescriptor* field) const {
265   return (field->type() == FieldDescriptor::TYPE_MESSAGE &&
266           schema_.IsEagerlyVerifiedLazyField(field));
267 }
268 
IsInlined(const FieldDescriptor * field) const269 bool Reflection::IsInlined(const FieldDescriptor* field) const {
270   return schema_.IsFieldInlined(field);
271 }
272 
SpaceUsedLong(const Message & message) const273 size_t Reflection::SpaceUsedLong(const Message& message) const {
274   // object_size_ already includes the in-memory representation of each field
275   // in the message, so we only need to account for additional memory used by
276   // the fields.
277   size_t total_size = schema_.GetObjectSize();
278 
279   total_size += GetUnknownFields(message).SpaceUsedExcludingSelfLong();
280 
281   // If this message owns an arena, add any unused space that's been allocated.
282   auto* arena = Arena::InternalGetArenaForAllocation(&message);
283   if (arena != nullptr && Arena::InternalGetOwningArena(&message) == nullptr &&
284       arena->InternalIsMessageOwnedArena()) {
285     total_size += arena->SpaceAllocated() - arena->SpaceUsed();
286   }
287 
288   if (schema_.HasExtensionSet()) {
289     total_size += GetExtensionSet(message).SpaceUsedExcludingSelfLong();
290   }
291   for (int i = 0; i <= last_non_weak_field_index_; i++) {
292     const FieldDescriptor* field = descriptor_->field(i);
293     if (field->is_repeated()) {
294       switch (field->cpp_type()) {
295 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                           \
296   case FieldDescriptor::CPPTYPE_##UPPERCASE:                        \
297     total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \
298                       .SpaceUsedExcludingSelfLong();                \
299     break
300 
301         HANDLE_TYPE(INT32, int32_t);
302         HANDLE_TYPE(INT64, int64_t);
303         HANDLE_TYPE(UINT32, uint32_t);
304         HANDLE_TYPE(UINT64, uint64_t);
305         HANDLE_TYPE(DOUBLE, double);
306         HANDLE_TYPE(FLOAT, float);
307         HANDLE_TYPE(BOOL, bool);
308         HANDLE_TYPE(ENUM, int);
309 #undef HANDLE_TYPE
310 
311         case FieldDescriptor::CPPTYPE_STRING:
312           switch (field->options().ctype()) {
313             default:  // TODO(kenton):  Support other string reps.
314             case FieldOptions::STRING:
315               total_size +=
316                   GetRaw<RepeatedPtrField<std::string> >(message, field)
317                       .SpaceUsedExcludingSelfLong();
318               break;
319           }
320           break;
321 
322         case FieldDescriptor::CPPTYPE_MESSAGE:
323           if (IsMapFieldInApi(field)) {
324             total_size += GetRaw<internal::MapFieldBase>(message, field)
325                               .SpaceUsedExcludingSelfLong();
326           } else {
327             // We don't know which subclass of RepeatedPtrFieldBase the type is,
328             // so we use RepeatedPtrFieldBase directly.
329             total_size +=
330                 GetRaw<RepeatedPtrFieldBase>(message, field)
331                     .SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >();
332           }
333 
334           break;
335       }
336     } else {
337       if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
338         continue;
339       }
340       switch (field->cpp_type()) {
341         case FieldDescriptor::CPPTYPE_INT32:
342         case FieldDescriptor::CPPTYPE_INT64:
343         case FieldDescriptor::CPPTYPE_UINT32:
344         case FieldDescriptor::CPPTYPE_UINT64:
345         case FieldDescriptor::CPPTYPE_DOUBLE:
346         case FieldDescriptor::CPPTYPE_FLOAT:
347         case FieldDescriptor::CPPTYPE_BOOL:
348         case FieldDescriptor::CPPTYPE_ENUM:
349           // Field is inline, so we've already counted it.
350           break;
351 
352         case FieldDescriptor::CPPTYPE_STRING: {
353           switch (field->options().ctype()) {
354             default:  // TODO(kenton):  Support other string reps.
355             case FieldOptions::STRING:
356               if (IsInlined(field)) {
357                 const std::string* ptr =
358                     &GetField<InlinedStringField>(message, field).GetNoArena();
359                 total_size += StringSpaceUsedExcludingSelfLong(*ptr);
360               } else {
361                 // Initially, the string points to the default value stored
362                 // in the prototype. Only count the string if it has been
363                 // changed from the default value.
364                 // Except oneof fields, those never point to a default instance,
365                 // and there is no default instance to point to.
366                 const auto& str = GetField<ArenaStringPtr>(message, field);
367                 if (!str.IsDefault() || schema_.InRealOneof(field)) {
368                   // string fields are represented by just a pointer, so also
369                   // include sizeof(string) as well.
370                   total_size += sizeof(std::string) +
371                                 StringSpaceUsedExcludingSelfLong(str.Get());
372                 }
373               }
374               break;
375           }
376           break;
377         }
378 
379         case FieldDescriptor::CPPTYPE_MESSAGE:
380           if (schema_.IsDefaultInstance(message)) {
381             // For singular fields, the prototype just stores a pointer to the
382             // external type's prototype, so there is no extra memory usage.
383           } else {
384             const Message* sub_message = GetRaw<const Message*>(message, field);
385             if (sub_message != nullptr) {
386               total_size += sub_message->SpaceUsedLong();
387             }
388           }
389           break;
390       }
391     }
392   }
393   return total_size;
394 }
395 
396 namespace {
397 
398 template <bool unsafe_shallow_swap>
399 struct OneofFieldMover {
400   template <typename FromType, typename ToType>
operator ()google::protobuf::__anon78a4ad0c0311::OneofFieldMover401   void operator()(const FieldDescriptor* field, FromType* from, ToType* to) {
402     switch (field->cpp_type()) {
403       case FieldDescriptor::CPPTYPE_INT32:
404         to->SetInt32(from->GetInt32());
405         break;
406       case FieldDescriptor::CPPTYPE_INT64:
407         to->SetInt64(from->GetInt64());
408         break;
409       case FieldDescriptor::CPPTYPE_UINT32:
410         to->SetUint32(from->GetUint32());
411         break;
412       case FieldDescriptor::CPPTYPE_UINT64:
413         to->SetUint64(from->GetUint64());
414         break;
415       case FieldDescriptor::CPPTYPE_FLOAT:
416         to->SetFloat(from->GetFloat());
417         break;
418       case FieldDescriptor::CPPTYPE_DOUBLE:
419         to->SetDouble(from->GetDouble());
420         break;
421       case FieldDescriptor::CPPTYPE_BOOL:
422         to->SetBool(from->GetBool());
423         break;
424       case FieldDescriptor::CPPTYPE_ENUM:
425         to->SetEnum(from->GetEnum());
426         break;
427       case FieldDescriptor::CPPTYPE_MESSAGE:
428         if (!unsafe_shallow_swap) {
429           to->SetMessage(from->GetMessage());
430         } else {
431           to->UnsafeSetMessage(from->UnsafeGetMessage());
432         }
433         break;
434       case FieldDescriptor::CPPTYPE_STRING:
435         if (!unsafe_shallow_swap) {
436           to->SetString(from->GetString());
437           break;
438         }
439         switch (field->options().ctype()) {
440           default:
441           case FieldOptions::STRING: {
442             to->SetArenaStringPtr(from->GetArenaStringPtr());
443             break;
444           }
445         }
446         break;
447       default:
448         GOOGLE_LOG(FATAL) << "unimplemented type: " << field->cpp_type();
449     }
450     if (unsafe_shallow_swap) {
451       // Not clearing oneof case after move may cause unwanted "ClearOneof"
452       // where the residual message or string value is deleted and causes
453       // use-after-free (only for unsafe swap).
454       from->ClearOneofCase();
455     }
456   }
457 };
458 
459 }  // namespace
460 
461 namespace internal {
462 
463 class SwapFieldHelper {
464  public:
465   template <bool unsafe_shallow_swap>
466   static void SwapRepeatedStringField(const Reflection* r, Message* lhs,
467                                       Message* rhs,
468                                       const FieldDescriptor* field);
469 
470   template <bool unsafe_shallow_swap>
471   static void SwapInlinedStrings(const Reflection* r, Message* lhs,
472                                  Message* rhs, const FieldDescriptor* field);
473 
474   template <bool unsafe_shallow_swap>
475   static void SwapNonInlinedStrings(const Reflection* r, Message* lhs,
476                                     Message* rhs, const FieldDescriptor* field);
477 
478   template <bool unsafe_shallow_swap>
479   static void SwapStringField(const Reflection* r, Message* lhs, Message* rhs,
480                               const FieldDescriptor* field);
481 
482   static void SwapArenaStringPtr(ArenaStringPtr* lhs, Arena* lhs_arena,
483                                  ArenaStringPtr* rhs, Arena* rhs_arena);
484 
485   template <bool unsafe_shallow_swap>
486   static void SwapRepeatedMessageField(const Reflection* r, Message* lhs,
487                                        Message* rhs,
488                                        const FieldDescriptor* field);
489 
490   template <bool unsafe_shallow_swap>
491   static void SwapMessageField(const Reflection* r, Message* lhs, Message* rhs,
492                                const FieldDescriptor* field);
493 
494   static void SwapMessage(const Reflection* r, Message* lhs, Arena* lhs_arena,
495                           Message* rhs, Arena* rhs_arena,
496                           const FieldDescriptor* field);
497 
498   static void SwapNonMessageNonStringField(const Reflection* r, Message* lhs,
499                                            Message* rhs,
500                                            const FieldDescriptor* field);
501 };
502 
503 template <bool unsafe_shallow_swap>
SwapRepeatedStringField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)504 void SwapFieldHelper::SwapRepeatedStringField(const Reflection* r, Message* lhs,
505                                               Message* rhs,
506                                               const FieldDescriptor* field) {
507   switch (field->options().ctype()) {
508     default:
509     case FieldOptions::STRING: {
510       auto* lhs_string = r->MutableRaw<RepeatedPtrFieldBase>(lhs, field);
511       auto* rhs_string = r->MutableRaw<RepeatedPtrFieldBase>(rhs, field);
512       if (unsafe_shallow_swap) {
513         lhs_string->InternalSwap(rhs_string);
514       } else {
515         lhs_string->Swap<GenericTypeHandler<std::string>>(rhs_string);
516       }
517       break;
518     }
519   }
520 }
521 
522 template <bool unsafe_shallow_swap>
SwapInlinedStrings(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)523 void SwapFieldHelper::SwapInlinedStrings(const Reflection* r, Message* lhs,
524                                          Message* rhs,
525                                          const FieldDescriptor* field) {
526   // Inlined string field.
527   Arena* lhs_arena = lhs->GetArenaForAllocation();
528   Arena* rhs_arena = rhs->GetArenaForAllocation();
529   auto* lhs_string = r->MutableRaw<InlinedStringField>(lhs, field);
530   auto* rhs_string = r->MutableRaw<InlinedStringField>(rhs, field);
531   uint32_t index = r->schema_.InlinedStringIndex(field);
532   GOOGLE_DCHECK_GT(index, 0);
533   uint32_t* lhs_array = r->MutableInlinedStringDonatedArray(lhs);
534   uint32_t* rhs_array = r->MutableInlinedStringDonatedArray(rhs);
535   uint32_t* lhs_state = &lhs_array[index / 32];
536   uint32_t* rhs_state = &rhs_array[index / 32];
537   bool lhs_arena_dtor_registered = (lhs_array[0] & 0x1u) == 0;
538   bool rhs_arena_dtor_registered = (rhs_array[0] & 0x1u) == 0;
539   const uint32_t mask = ~(static_cast<uint32_t>(1) << (index % 32));
540   if (unsafe_shallow_swap || lhs_arena == rhs_arena) {
541     InlinedStringField::InternalSwap(lhs_string, lhs_arena,
542                                      lhs_arena_dtor_registered, lhs, rhs_string,
543                                      rhs_arena, rhs_arena_dtor_registered, rhs);
544   } else {
545     const std::string temp = lhs_string->Get();
546     lhs_string->Set(rhs_string->Get(), lhs_arena,
547                     r->IsInlinedStringDonated(*lhs, field), lhs_state, mask,
548                     lhs);
549     rhs_string->Set(temp, rhs_arena, r->IsInlinedStringDonated(*rhs, field),
550                     rhs_state, mask, rhs);
551   }
552 }
553 
554 template <bool unsafe_shallow_swap>
SwapNonInlinedStrings(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)555 void SwapFieldHelper::SwapNonInlinedStrings(const Reflection* r, Message* lhs,
556                                             Message* rhs,
557                                             const FieldDescriptor* field) {
558   ArenaStringPtr* lhs_string = r->MutableRaw<ArenaStringPtr>(lhs, field);
559   ArenaStringPtr* rhs_string = r->MutableRaw<ArenaStringPtr>(rhs, field);
560   if (unsafe_shallow_swap) {
561     ArenaStringPtr::UnsafeShallowSwap(lhs_string, rhs_string);
562   } else {
563     SwapFieldHelper::SwapArenaStringPtr(
564         lhs_string, lhs->GetArenaForAllocation(),  //
565         rhs_string, rhs->GetArenaForAllocation());
566   }
567 }
568 
569 template <bool unsafe_shallow_swap>
SwapStringField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)570 void SwapFieldHelper::SwapStringField(const Reflection* r, Message* lhs,
571                                       Message* rhs,
572                                       const FieldDescriptor* field) {
573   switch (field->options().ctype()) {
574     default:
575     case FieldOptions::STRING: {
576       if (r->IsInlined(field)) {
577         SwapFieldHelper::SwapInlinedStrings<unsafe_shallow_swap>(r, lhs, rhs,
578                                                                  field);
579       } else {
580         SwapFieldHelper::SwapNonInlinedStrings<unsafe_shallow_swap>(r, lhs, rhs,
581                                                                     field);
582       }
583       break;
584     }
585   }
586 }
587 
SwapArenaStringPtr(ArenaStringPtr * lhs,Arena * lhs_arena,ArenaStringPtr * rhs,Arena * rhs_arena)588 void SwapFieldHelper::SwapArenaStringPtr(ArenaStringPtr* lhs, Arena* lhs_arena,
589                                          ArenaStringPtr* rhs,
590                                          Arena* rhs_arena) {
591   if (lhs_arena == rhs_arena) {
592     ArenaStringPtr::InternalSwap(lhs, lhs_arena, rhs, rhs_arena);
593   } else if (lhs->IsDefault() && rhs->IsDefault()) {
594     // Nothing to do.
595   } else if (lhs->IsDefault()) {
596     lhs->Set(rhs->Get(), lhs_arena);
597     // rhs needs to be destroyed before overwritten.
598     rhs->Destroy();
599     rhs->InitDefault();
600   } else if (rhs->IsDefault()) {
601     rhs->Set(lhs->Get(), rhs_arena);
602     // lhs needs to be destroyed before overwritten.
603     lhs->Destroy();
604     lhs->InitDefault();
605   } else {
606     std::string temp = lhs->Get();
607     lhs->Set(rhs->Get(), lhs_arena);
608     rhs->Set(std::move(temp), rhs_arena);
609   }
610 }
611 
612 template <bool unsafe_shallow_swap>
SwapRepeatedMessageField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)613 void SwapFieldHelper::SwapRepeatedMessageField(const Reflection* r,
614                                                Message* lhs, Message* rhs,
615                                                const FieldDescriptor* field) {
616   if (IsMapFieldInApi(field)) {
617     auto* lhs_map = r->MutableRaw<MapFieldBase>(lhs, field);
618     auto* rhs_map = r->MutableRaw<MapFieldBase>(rhs, field);
619     if (unsafe_shallow_swap) {
620       lhs_map->UnsafeShallowSwap(rhs_map);
621     } else {
622       lhs_map->Swap(rhs_map);
623     }
624   } else {
625     auto* lhs_rm = r->MutableRaw<RepeatedPtrFieldBase>(lhs, field);
626     auto* rhs_rm = r->MutableRaw<RepeatedPtrFieldBase>(rhs, field);
627     if (unsafe_shallow_swap) {
628       lhs_rm->InternalSwap(rhs_rm);
629     } else {
630       lhs_rm->Swap<GenericTypeHandler<Message>>(rhs_rm);
631     }
632   }
633 }
634 
635 template <bool unsafe_shallow_swap>
SwapMessageField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)636 void SwapFieldHelper::SwapMessageField(const Reflection* r, Message* lhs,
637                                        Message* rhs,
638                                        const FieldDescriptor* field) {
639   if (unsafe_shallow_swap) {
640     std::swap(*r->MutableRaw<Message*>(lhs, field),
641               *r->MutableRaw<Message*>(rhs, field));
642   } else {
643     SwapMessage(r, lhs, lhs->GetArenaForAllocation(), rhs,
644                 rhs->GetArenaForAllocation(), field);
645   }
646 }
647 
SwapMessage(const Reflection * r,Message * lhs,Arena * lhs_arena,Message * rhs,Arena * rhs_arena,const FieldDescriptor * field)648 void SwapFieldHelper::SwapMessage(const Reflection* r, Message* lhs,
649                                   Arena* lhs_arena, Message* rhs,
650                                   Arena* rhs_arena,
651                                   const FieldDescriptor* field) {
652   Message** lhs_sub = r->MutableRaw<Message*>(lhs, field);
653   Message** rhs_sub = r->MutableRaw<Message*>(rhs, field);
654 
655   if (*lhs_sub == *rhs_sub) return;
656 
657 #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
658   if (lhs_arena != nullptr && lhs_arena == rhs_arena) {
659 #else   // PROTOBUF_FORCE_COPY_IN_SWAP
660   if (lhs_arena == rhs_arena) {
661 #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
662     std::swap(*lhs_sub, *rhs_sub);
663     return;
664   }
665 
666   if (*lhs_sub != nullptr && *rhs_sub != nullptr) {
667     (*lhs_sub)->GetReflection()->Swap(*lhs_sub, *rhs_sub);
668   } else if (*lhs_sub == nullptr && r->HasBit(*rhs, field)) {
669     *lhs_sub = (*rhs_sub)->New(lhs_arena);
670     (*lhs_sub)->CopyFrom(**rhs_sub);
671     r->ClearField(rhs, field);
672     // Ensures has bit is unchanged after ClearField.
673     r->SetBit(rhs, field);
674   } else if (*rhs_sub == nullptr && r->HasBit(*lhs, field)) {
675     *rhs_sub = (*lhs_sub)->New(rhs_arena);
676     (*rhs_sub)->CopyFrom(**lhs_sub);
677     r->ClearField(lhs, field);
678     // Ensures has bit is unchanged after ClearField.
679     r->SetBit(lhs, field);
680   }
681 }
682 
683 void SwapFieldHelper::SwapNonMessageNonStringField(
684     const Reflection* r, Message* lhs, Message* rhs,
685     const FieldDescriptor* field) {
686   switch (field->cpp_type()) {
687 #define SWAP_VALUES(CPPTYPE, TYPE)               \
688   case FieldDescriptor::CPPTYPE_##CPPTYPE:       \
689     std::swap(*r->MutableRaw<TYPE>(lhs, field),  \
690               *r->MutableRaw<TYPE>(rhs, field)); \
691     break;
692 
693     SWAP_VALUES(INT32, int32_t);
694     SWAP_VALUES(INT64, int64_t);
695     SWAP_VALUES(UINT32, uint32_t);
696     SWAP_VALUES(UINT64, uint64_t);
697     SWAP_VALUES(FLOAT, float);
698     SWAP_VALUES(DOUBLE, double);
699     SWAP_VALUES(BOOL, bool);
700     SWAP_VALUES(ENUM, int);
701 #undef SWAP_VALUES
702     default:
703       GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
704   }
705 }
706 
707 }  // namespace internal
708 
SwapField(Message * message1,Message * message2,const FieldDescriptor * field) const709 void Reflection::SwapField(Message* message1, Message* message2,
710                            const FieldDescriptor* field) const {
711   if (field->is_repeated()) {
712     switch (field->cpp_type()) {
713 #define SWAP_ARRAYS(CPPTYPE, TYPE)                                 \
714   case FieldDescriptor::CPPTYPE_##CPPTYPE:                         \
715     MutableRaw<RepeatedField<TYPE> >(message1, field)              \
716         ->Swap(MutableRaw<RepeatedField<TYPE> >(message2, field)); \
717     break;
718 
719       SWAP_ARRAYS(INT32, int32_t);
720       SWAP_ARRAYS(INT64, int64_t);
721       SWAP_ARRAYS(UINT32, uint32_t);
722       SWAP_ARRAYS(UINT64, uint64_t);
723       SWAP_ARRAYS(FLOAT, float);
724       SWAP_ARRAYS(DOUBLE, double);
725       SWAP_ARRAYS(BOOL, bool);
726       SWAP_ARRAYS(ENUM, int);
727 #undef SWAP_ARRAYS
728 
729       case FieldDescriptor::CPPTYPE_STRING:
730         internal::SwapFieldHelper::SwapRepeatedStringField<false>(
731             this, message1, message2, field);
732         break;
733       case FieldDescriptor::CPPTYPE_MESSAGE:
734         internal::SwapFieldHelper::SwapRepeatedMessageField<false>(
735             this, message1, message2, field);
736         break;
737 
738       default:
739         GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
740     }
741   } else {
742     switch (field->cpp_type()) {
743       case FieldDescriptor::CPPTYPE_MESSAGE:
744         internal::SwapFieldHelper::SwapMessageField<false>(this, message1,
745                                                            message2, field);
746         break;
747 
748       case FieldDescriptor::CPPTYPE_STRING:
749         internal::SwapFieldHelper::SwapStringField<false>(this, message1,
750                                                           message2, field);
751         break;
752       default:
753         internal::SwapFieldHelper::SwapNonMessageNonStringField(
754             this, message1, message2, field);
755     }
756   }
757 }
758 
UnsafeShallowSwapField(Message * message1,Message * message2,const FieldDescriptor * field) const759 void Reflection::UnsafeShallowSwapField(Message* message1, Message* message2,
760                                         const FieldDescriptor* field) const {
761   if (!field->is_repeated()) {
762     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
763       internal::SwapFieldHelper::SwapMessageField<true>(this, message1,
764                                                         message2, field);
765     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
766       internal::SwapFieldHelper::SwapStringField<true>(this, message1, message2,
767                                                        field);
768     } else {
769       internal::SwapFieldHelper::SwapNonMessageNonStringField(this, message1,
770                                                               message2, field);
771     }
772     return;
773   }
774 
775   switch (field->cpp_type()) {
776 #define SHALLOW_SWAP_ARRAYS(CPPTYPE, TYPE)                                \
777   case FieldDescriptor::CPPTYPE_##CPPTYPE:                                \
778     MutableRaw<RepeatedField<TYPE>>(message1, field)                      \
779         ->InternalSwap(MutableRaw<RepeatedField<TYPE>>(message2, field)); \
780     break;
781 
782     SHALLOW_SWAP_ARRAYS(INT32, int32_t);
783     SHALLOW_SWAP_ARRAYS(INT64, int64_t);
784     SHALLOW_SWAP_ARRAYS(UINT32, uint32_t);
785     SHALLOW_SWAP_ARRAYS(UINT64, uint64_t);
786     SHALLOW_SWAP_ARRAYS(FLOAT, float);
787     SHALLOW_SWAP_ARRAYS(DOUBLE, double);
788     SHALLOW_SWAP_ARRAYS(BOOL, bool);
789     SHALLOW_SWAP_ARRAYS(ENUM, int);
790 #undef SHALLOW_SWAP_ARRAYS
791 
792     case FieldDescriptor::CPPTYPE_STRING:
793       internal::SwapFieldHelper::SwapRepeatedStringField<true>(this, message1,
794                                                                message2, field);
795       break;
796     case FieldDescriptor::CPPTYPE_MESSAGE:
797       internal::SwapFieldHelper::SwapRepeatedMessageField<true>(
798           this, message1, message2, field);
799       break;
800 
801     default:
802       GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
803   }
804 }
805 
806 // Swaps oneof field between lhs and rhs. If unsafe_shallow_swap is true, it
807 // directly swaps oneof values; otherwise, it may involve copy/delete. Note that
808 // two messages may have different oneof cases. So, it has to be done in three
809 // steps (i.e. lhs -> temp, rhs -> lhs, temp -> rhs).
810 template <bool unsafe_shallow_swap>
SwapOneofField(Message * lhs,Message * rhs,const OneofDescriptor * oneof_descriptor) const811 void Reflection::SwapOneofField(Message* lhs, Message* rhs,
812                                 const OneofDescriptor* oneof_descriptor) const {
813   // Wraps a local variable to temporarily store oneof value.
814   struct LocalVarWrapper {
815 #define LOCAL_VAR_ACCESSOR(type, var, name)               \
816   type Get##name() const { return oneof_val.type_##var; } \
817   void Set##name(type v) { oneof_val.type_##var = v; }
818 
819     LOCAL_VAR_ACCESSOR(int32_t, int32, Int32);
820     LOCAL_VAR_ACCESSOR(int64_t, int64, Int64);
821     LOCAL_VAR_ACCESSOR(uint32_t, uint32, Uint32);
822     LOCAL_VAR_ACCESSOR(uint64_t, uint64, Uint64);
823     LOCAL_VAR_ACCESSOR(float, float, Float);
824     LOCAL_VAR_ACCESSOR(double, double, Double);
825     LOCAL_VAR_ACCESSOR(bool, bool, Bool);
826     LOCAL_VAR_ACCESSOR(int, enum, Enum);
827     LOCAL_VAR_ACCESSOR(Message*, message, Message);
828     LOCAL_VAR_ACCESSOR(ArenaStringPtr, arena_string_ptr, ArenaStringPtr);
829     const std::string& GetString() const { return string_val; }
830     void SetString(const std::string& v) { string_val = v; }
831     Message* UnsafeGetMessage() const { return GetMessage(); }
832     void UnsafeSetMessage(Message* v) { SetMessage(v); }
833     void ClearOneofCase() {}
834 
835     union {
836       int32_t type_int32;
837       int64_t type_int64;
838       uint32_t type_uint32;
839       uint64_t type_uint64;
840       float type_float;
841       double type_double;
842       bool type_bool;
843       int type_enum;
844       Message* type_message;
845       internal::ArenaStringPtr type_arena_string_ptr;
846     } oneof_val;
847 
848     // std::string cannot be in union.
849     std::string string_val;
850   };
851 
852   // Wraps a message pointer to read and write a field.
853   struct MessageWrapper {
854 #define MESSAGE_FIELD_ACCESSOR(type, var, name)         \
855   type Get##name() const {                              \
856     return reflection->GetField<type>(*message, field); \
857   }                                                     \
858   void Set##name(type v) { reflection->SetField<type>(message, field, v); }
859 
860     MESSAGE_FIELD_ACCESSOR(int32_t, int32, Int32);
861     MESSAGE_FIELD_ACCESSOR(int64_t, int64, Int64);
862     MESSAGE_FIELD_ACCESSOR(uint32_t, uint32, Uint32);
863     MESSAGE_FIELD_ACCESSOR(uint64_t, uint64, Uint64);
864     MESSAGE_FIELD_ACCESSOR(float, float, Float);
865     MESSAGE_FIELD_ACCESSOR(double, double, Double);
866     MESSAGE_FIELD_ACCESSOR(bool, bool, Bool);
867     MESSAGE_FIELD_ACCESSOR(int, enum, Enum);
868     MESSAGE_FIELD_ACCESSOR(ArenaStringPtr, arena_string_ptr, ArenaStringPtr);
869     std::string GetString() const {
870       return reflection->GetString(*message, field);
871     }
872     void SetString(const std::string& v) {
873       reflection->SetString(message, field, v);
874     }
875     Message* GetMessage() const {
876       return reflection->ReleaseMessage(message, field);
877     }
878     void SetMessage(Message* v) {
879       reflection->SetAllocatedMessage(message, v, field);
880     }
881     Message* UnsafeGetMessage() const {
882       return reflection->UnsafeArenaReleaseMessage(message, field);
883     }
884     void UnsafeSetMessage(Message* v) {
885       reflection->UnsafeArenaSetAllocatedMessage(message, v, field);
886     }
887     void ClearOneofCase() {
888       *reflection->MutableOneofCase(message, field->containing_oneof()) = 0;
889     }
890 
891     const Reflection* reflection;
892     Message* message;
893     const FieldDescriptor* field;
894   };
895 
896   GOOGLE_DCHECK(!oneof_descriptor->is_synthetic());
897   uint32_t oneof_case_lhs = GetOneofCase(*lhs, oneof_descriptor);
898   uint32_t oneof_case_rhs = GetOneofCase(*rhs, oneof_descriptor);
899 
900   LocalVarWrapper temp;
901   MessageWrapper lhs_wrapper, rhs_wrapper;
902   const FieldDescriptor* field_lhs = nullptr;
903   OneofFieldMover<unsafe_shallow_swap> mover;
904   // lhs --> temp
905   if (oneof_case_lhs > 0) {
906     field_lhs = descriptor_->FindFieldByNumber(oneof_case_lhs);
907     lhs_wrapper = {this, lhs, field_lhs};
908     mover(field_lhs, &lhs_wrapper, &temp);
909   }
910   // rhs --> lhs
911   if (oneof_case_rhs > 0) {
912     const FieldDescriptor* f = descriptor_->FindFieldByNumber(oneof_case_rhs);
913     lhs_wrapper = {this, lhs, f};
914     rhs_wrapper = {this, rhs, f};
915     mover(f, &rhs_wrapper, &lhs_wrapper);
916   } else if (!unsafe_shallow_swap) {
917     ClearOneof(lhs, oneof_descriptor);
918   }
919   // temp --> rhs
920   if (oneof_case_lhs > 0) {
921     rhs_wrapper = {this, rhs, field_lhs};
922     mover(field_lhs, &temp, &rhs_wrapper);
923   } else if (!unsafe_shallow_swap) {
924     ClearOneof(rhs, oneof_descriptor);
925   }
926 
927   if (unsafe_shallow_swap) {
928     *MutableOneofCase(lhs, oneof_descriptor) = oneof_case_rhs;
929     *MutableOneofCase(rhs, oneof_descriptor) = oneof_case_lhs;
930   }
931 }
932 
Swap(Message * message1,Message * message2) const933 void Reflection::Swap(Message* message1, Message* message2) const {
934   if (message1 == message2) return;
935 
936   // TODO(kenton):  Other Reflection methods should probably check this too.
937   GOOGLE_CHECK_EQ(message1->GetReflection(), this)
938       << "First argument to Swap() (of type \""
939       << message1->GetDescriptor()->full_name()
940       << "\") is not compatible with this reflection object (which is for type "
941          "\""
942       << descriptor_->full_name()
943       << "\").  Note that the exact same class is required; not just the same "
944          "descriptor.";
945   GOOGLE_CHECK_EQ(message2->GetReflection(), this)
946       << "Second argument to Swap() (of type \""
947       << message2->GetDescriptor()->full_name()
948       << "\") is not compatible with this reflection object (which is for type "
949          "\""
950       << descriptor_->full_name()
951       << "\").  Note that the exact same class is required; not just the same "
952          "descriptor.";
953 
954   // Check that both messages are in the same arena (or both on the heap). We
955   // need to copy all data if not, due to ownership semantics.
956 #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
957   if (message1->GetOwningArena() == nullptr ||
958       message1->GetOwningArena() != message2->GetOwningArena()) {
959 #else   // PROTOBUF_FORCE_COPY_IN_SWAP
960   if (message1->GetOwningArena() != message2->GetOwningArena()) {
961 #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
962     // One of the two is guaranteed to have an arena.  Switch things around
963     // to guarantee that message1 has an arena.
964     Arena* arena = message1->GetOwningArena();
965     if (arena == nullptr) {
966       arena = message2->GetOwningArena();
967       std::swap(message1, message2);  // Swapping names for pointers!
968     }
969 
970     Message* temp = message1->New(arena);
971     temp->MergeFrom(*message2);
972     message2->CopyFrom(*message1);
973 #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
974     message1->CopyFrom(*temp);
975     if (arena == nullptr) delete temp;
976 #else   // PROTOBUF_FORCE_COPY_IN_SWAP
977     Swap(message1, temp);
978 #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
979     return;
980   }
981 
982   GOOGLE_DCHECK_EQ(message1->GetOwningArena(), message2->GetOwningArena());
983 
984   UnsafeArenaSwap(message1, message2);
985 }
986 
987 template <bool unsafe_shallow_swap>
988 void Reflection::SwapFieldsImpl(
989     Message* message1, Message* message2,
990     const std::vector<const FieldDescriptor*>& fields) const {
991   if (message1 == message2) return;
992 
993   // TODO(kenton):  Other Reflection methods should probably check this too.
994   GOOGLE_CHECK_EQ(message1->GetReflection(), this)
995       << "First argument to SwapFields() (of type \""
996       << message1->GetDescriptor()->full_name()
997       << "\") is not compatible with this reflection object (which is for type "
998          "\""
999       << descriptor_->full_name()
1000       << "\").  Note that the exact same class is required; not just the same "
1001          "descriptor.";
1002   GOOGLE_CHECK_EQ(message2->GetReflection(), this)
1003       << "Second argument to SwapFields() (of type \""
1004       << message2->GetDescriptor()->full_name()
1005       << "\") is not compatible with this reflection object (which is for type "
1006          "\""
1007       << descriptor_->full_name()
1008       << "\").  Note that the exact same class is required; not just the same "
1009          "descriptor.";
1010 
1011   std::set<int> swapped_oneof;
1012 
1013   GOOGLE_DCHECK(!unsafe_shallow_swap || message1->GetArenaForAllocation() ==
1014                                      message2->GetArenaForAllocation());
1015 
1016   const Message* prototype =
1017       message_factory_->GetPrototype(message1->GetDescriptor());
1018   for (const auto* field : fields) {
1019     CheckInvalidAccess(schema_, field);
1020     if (field->is_extension()) {
1021       if (unsafe_shallow_swap) {
1022         MutableExtensionSet(message1)->UnsafeShallowSwapExtension(
1023             MutableExtensionSet(message2), field->number());
1024       } else {
1025         MutableExtensionSet(message1)->SwapExtension(
1026             prototype, MutableExtensionSet(message2), field->number());
1027       }
1028     } else {
1029       if (schema_.InRealOneof(field)) {
1030         int oneof_index = field->containing_oneof()->index();
1031         // Only swap the oneof field once.
1032         if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
1033           continue;
1034         }
1035         swapped_oneof.insert(oneof_index);
1036         SwapOneofField<unsafe_shallow_swap>(message1, message2,
1037                                             field->containing_oneof());
1038       } else {
1039         // Swap field.
1040         if (unsafe_shallow_swap) {
1041           UnsafeShallowSwapField(message1, message2, field);
1042         } else {
1043           SwapField(message1, message2, field);
1044         }
1045         // Swap has bit for non-repeated fields.  We have already checked for
1046         // oneof already. This has to be done after SwapField, because SwapField
1047         // may depend on the information in has bits.
1048         if (!field->is_repeated()) {
1049           SwapBit(message1, message2, field);
1050           if (field->options().ctype() == FieldOptions::STRING &&
1051               IsInlined(field)) {
1052             GOOGLE_DCHECK(!unsafe_shallow_swap ||
1053                    message1->GetArenaForAllocation() ==
1054                        message2->GetArenaForAllocation());
1055             SwapInlinedStringDonated(message1, message2, field);
1056           }
1057         }
1058       }
1059     }
1060   }
1061 }
1062 
1063 void Reflection::SwapFields(
1064     Message* message1, Message* message2,
1065     const std::vector<const FieldDescriptor*>& fields) const {
1066   SwapFieldsImpl<false>(message1, message2, fields);
1067 }
1068 
1069 void Reflection::UnsafeShallowSwapFields(
1070     Message* message1, Message* message2,
1071     const std::vector<const FieldDescriptor*>& fields) const {
1072   SwapFieldsImpl<true>(message1, message2, fields);
1073 }
1074 
1075 void Reflection::UnsafeArenaSwapFields(
1076     Message* lhs, Message* rhs,
1077     const std::vector<const FieldDescriptor*>& fields) const {
1078   GOOGLE_DCHECK_EQ(lhs->GetArenaForAllocation(), rhs->GetArenaForAllocation());
1079   UnsafeShallowSwapFields(lhs, rhs, fields);
1080 }
1081 
1082 // -------------------------------------------------------------------
1083 
1084 bool Reflection::HasField(const Message& message,
1085                           const FieldDescriptor* field) const {
1086   USAGE_CHECK_MESSAGE_TYPE(HasField);
1087   USAGE_CHECK_SINGULAR(HasField);
1088   CheckInvalidAccess(schema_, field);
1089 
1090   if (field->is_extension()) {
1091     return GetExtensionSet(message).Has(field->number());
1092   } else {
1093     if (schema_.InRealOneof(field)) {
1094       return HasOneofField(message, field);
1095     } else {
1096       return HasBit(message, field);
1097     }
1098   }
1099 }
1100 
1101 void Reflection::UnsafeArenaSwap(Message* lhs, Message* rhs) const {
1102   if (lhs == rhs) return;
1103 
1104   MutableInternalMetadata(lhs)->InternalSwap(MutableInternalMetadata(rhs));
1105 
1106   for (int i = 0; i <= last_non_weak_field_index_; i++) {
1107     const FieldDescriptor* field = descriptor_->field(i);
1108     if (schema_.InRealOneof(field)) continue;
1109     if (schema_.IsFieldStripped(field)) continue;
1110     UnsafeShallowSwapField(lhs, rhs, field);
1111   }
1112   const int oneof_decl_count = descriptor_->oneof_decl_count();
1113   for (int i = 0; i < oneof_decl_count; i++) {
1114     const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
1115     if (!oneof->is_synthetic()) {
1116       SwapOneofField<true>(lhs, rhs, oneof);
1117     }
1118   }
1119 
1120   // Swapping bits need to happen after swapping fields, because the latter may
1121   // depend on the has bit information.
1122   if (schema_.HasHasbits()) {
1123     uint32_t* lhs_has_bits = MutableHasBits(lhs);
1124     uint32_t* rhs_has_bits = MutableHasBits(rhs);
1125 
1126     int fields_with_has_bits = 0;
1127     for (int i = 0; i < descriptor_->field_count(); i++) {
1128       const FieldDescriptor* field = descriptor_->field(i);
1129       if (field->is_repeated() || schema_.InRealOneof(field)) {
1130         continue;
1131       }
1132       fields_with_has_bits++;
1133     }
1134 
1135     int has_bits_size = (fields_with_has_bits + 31) / 32;
1136 
1137     for (int i = 0; i < has_bits_size; i++) {
1138       std::swap(lhs_has_bits[i], rhs_has_bits[i]);
1139     }
1140   }
1141 
1142   if (schema_.HasInlinedString()) {
1143     uint32_t* lhs_donated_array = MutableInlinedStringDonatedArray(lhs);
1144     uint32_t* rhs_donated_array = MutableInlinedStringDonatedArray(rhs);
1145     int inlined_string_count = 0;
1146     for (int i = 0; i < descriptor_->field_count(); i++) {
1147       const FieldDescriptor* field = descriptor_->field(i);
1148       if (field->is_extension() || field->is_repeated() ||
1149           schema_.InRealOneof(field) ||
1150           field->options().ctype() != FieldOptions::STRING ||
1151           !IsInlined(field)) {
1152         continue;
1153       }
1154       inlined_string_count++;
1155     }
1156 
1157     int donated_array_size = inlined_string_count == 0
1158                                  ? 0
1159                                  // One extra bit for the arena dtor tracking.
1160                                  : (inlined_string_count + 1 + 31) / 32;
1161     GOOGLE_CHECK_EQ((lhs_donated_array[0] & 0x1u) == 0,
1162              (rhs_donated_array[0] & 0x1u) == 0);
1163     for (int i = 0; i < donated_array_size; i++) {
1164       std::swap(lhs_donated_array[i], rhs_donated_array[i]);
1165     }
1166   }
1167 
1168   if (schema_.HasExtensionSet()) {
1169     MutableExtensionSet(lhs)->InternalSwap(MutableExtensionSet(rhs));
1170   }
1171 }
1172 
1173 int Reflection::FieldSize(const Message& message,
1174                           const FieldDescriptor* field) const {
1175   USAGE_CHECK_MESSAGE_TYPE(FieldSize);
1176   USAGE_CHECK_REPEATED(FieldSize);
1177   CheckInvalidAccess(schema_, field);
1178 
1179   if (field->is_extension()) {
1180     return GetExtensionSet(message).ExtensionSize(field->number());
1181   } else {
1182     switch (field->cpp_type()) {
1183 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)    \
1184   case FieldDescriptor::CPPTYPE_##UPPERCASE: \
1185     return GetRaw<RepeatedField<LOWERCASE> >(message, field).size()
1186 
1187       HANDLE_TYPE(INT32, int32_t);
1188       HANDLE_TYPE(INT64, int64_t);
1189       HANDLE_TYPE(UINT32, uint32_t);
1190       HANDLE_TYPE(UINT64, uint64_t);
1191       HANDLE_TYPE(DOUBLE, double);
1192       HANDLE_TYPE(FLOAT, float);
1193       HANDLE_TYPE(BOOL, bool);
1194       HANDLE_TYPE(ENUM, int);
1195 #undef HANDLE_TYPE
1196 
1197       case FieldDescriptor::CPPTYPE_STRING:
1198       case FieldDescriptor::CPPTYPE_MESSAGE:
1199         if (IsMapFieldInApi(field)) {
1200           const internal::MapFieldBase& map =
1201               GetRaw<MapFieldBase>(message, field);
1202           if (map.IsRepeatedFieldValid()) {
1203             return map.GetRepeatedField().size();
1204           } else {
1205             // No need to materialize the repeated field if it is out of sync:
1206             // its size will be the same as the map's size.
1207             return map.size();
1208           }
1209         } else {
1210           return GetRaw<RepeatedPtrFieldBase>(message, field).size();
1211         }
1212     }
1213 
1214     GOOGLE_LOG(FATAL) << "Can't get here.";
1215     return 0;
1216   }
1217 }
1218 
1219 void Reflection::ClearField(Message* message,
1220                             const FieldDescriptor* field) const {
1221   USAGE_CHECK_MESSAGE_TYPE(ClearField);
1222   CheckInvalidAccess(schema_, field);
1223 
1224   if (field->is_extension()) {
1225     MutableExtensionSet(message)->ClearExtension(field->number());
1226   } else if (!field->is_repeated()) {
1227     if (schema_.InRealOneof(field)) {
1228       ClearOneofField(message, field);
1229       return;
1230     }
1231     if (HasBit(*message, field)) {
1232       ClearBit(message, field);
1233 
1234       // We need to set the field back to its default value.
1235       switch (field->cpp_type()) {
1236 #define CLEAR_TYPE(CPPTYPE, TYPE)                                      \
1237   case FieldDescriptor::CPPTYPE_##CPPTYPE:                             \
1238     *MutableRaw<TYPE>(message, field) = field->default_value_##TYPE(); \
1239     break;
1240 
1241         CLEAR_TYPE(INT32, int32_t);
1242         CLEAR_TYPE(INT64, int64_t);
1243         CLEAR_TYPE(UINT32, uint32_t);
1244         CLEAR_TYPE(UINT64, uint64_t);
1245         CLEAR_TYPE(FLOAT, float);
1246         CLEAR_TYPE(DOUBLE, double);
1247         CLEAR_TYPE(BOOL, bool);
1248 #undef CLEAR_TYPE
1249 
1250         case FieldDescriptor::CPPTYPE_ENUM:
1251           *MutableRaw<int>(message, field) =
1252               field->default_value_enum()->number();
1253           break;
1254 
1255         case FieldDescriptor::CPPTYPE_STRING: {
1256           switch (field->options().ctype()) {
1257             default:  // TODO(kenton):  Support other string reps.
1258             case FieldOptions::STRING:
1259               if (IsInlined(field)) {
1260                 // Currently, string with default value can't be inlined. So we
1261                 // don't have to handle default value here.
1262                 MutableRaw<InlinedStringField>(message, field)->ClearToEmpty();
1263               } else {
1264                 auto* str = MutableRaw<ArenaStringPtr>(message, field);
1265                 str->Destroy();
1266                 str->InitDefault();
1267               }
1268               break;
1269           }
1270           break;
1271         }
1272 
1273         case FieldDescriptor::CPPTYPE_MESSAGE:
1274           if (schema_.HasBitIndex(field) == static_cast<uint32_t>(-1)) {
1275             // Proto3 does not have has-bits and we need to set a message field
1276             // to nullptr in order to indicate its un-presence.
1277             if (message->GetArenaForAllocation() == nullptr) {
1278               delete *MutableRaw<Message*>(message, field);
1279             }
1280             *MutableRaw<Message*>(message, field) = nullptr;
1281           } else {
1282             (*MutableRaw<Message*>(message, field))->Clear();
1283           }
1284           break;
1285       }
1286     }
1287   } else {
1288     switch (field->cpp_type()) {
1289 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                           \
1290   case FieldDescriptor::CPPTYPE_##UPPERCASE:                        \
1291     MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear(); \
1292     break
1293 
1294       HANDLE_TYPE(INT32, int32_t);
1295       HANDLE_TYPE(INT64, int64_t);
1296       HANDLE_TYPE(UINT32, uint32_t);
1297       HANDLE_TYPE(UINT64, uint64_t);
1298       HANDLE_TYPE(DOUBLE, double);
1299       HANDLE_TYPE(FLOAT, float);
1300       HANDLE_TYPE(BOOL, bool);
1301       HANDLE_TYPE(ENUM, int);
1302 #undef HANDLE_TYPE
1303 
1304       case FieldDescriptor::CPPTYPE_STRING: {
1305         switch (field->options().ctype()) {
1306           default:  // TODO(kenton):  Support other string reps.
1307           case FieldOptions::STRING:
1308             MutableRaw<RepeatedPtrField<std::string> >(message, field)->Clear();
1309             break;
1310         }
1311         break;
1312       }
1313 
1314       case FieldDescriptor::CPPTYPE_MESSAGE: {
1315         if (IsMapFieldInApi(field)) {
1316           MutableRaw<MapFieldBase>(message, field)->Clear();
1317         } else {
1318           // We don't know which subclass of RepeatedPtrFieldBase the type is,
1319           // so we use RepeatedPtrFieldBase directly.
1320           MutableRaw<RepeatedPtrFieldBase>(message, field)
1321               ->Clear<GenericTypeHandler<Message> >();
1322         }
1323         break;
1324       }
1325     }
1326   }
1327 }
1328 
1329 void Reflection::RemoveLast(Message* message,
1330                             const FieldDescriptor* field) const {
1331   USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
1332   USAGE_CHECK_REPEATED(RemoveLast);
1333   CheckInvalidAccess(schema_, field);
1334 
1335   if (field->is_extension()) {
1336     MutableExtensionSet(message)->RemoveLast(field->number());
1337   } else {
1338     switch (field->cpp_type()) {
1339 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                \
1340   case FieldDescriptor::CPPTYPE_##UPPERCASE:                             \
1341     MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast(); \
1342     break
1343 
1344       HANDLE_TYPE(INT32, int32_t);
1345       HANDLE_TYPE(INT64, int64_t);
1346       HANDLE_TYPE(UINT32, uint32_t);
1347       HANDLE_TYPE(UINT64, uint64_t);
1348       HANDLE_TYPE(DOUBLE, double);
1349       HANDLE_TYPE(FLOAT, float);
1350       HANDLE_TYPE(BOOL, bool);
1351       HANDLE_TYPE(ENUM, int);
1352 #undef HANDLE_TYPE
1353 
1354       case FieldDescriptor::CPPTYPE_STRING:
1355         switch (field->options().ctype()) {
1356           default:  // TODO(kenton):  Support other string reps.
1357           case FieldOptions::STRING:
1358             MutableRaw<RepeatedPtrField<std::string> >(message, field)
1359                 ->RemoveLast();
1360             break;
1361         }
1362         break;
1363 
1364       case FieldDescriptor::CPPTYPE_MESSAGE:
1365         if (IsMapFieldInApi(field)) {
1366           MutableRaw<MapFieldBase>(message, field)
1367               ->MutableRepeatedField()
1368               ->RemoveLast<GenericTypeHandler<Message> >();
1369         } else {
1370           MutableRaw<RepeatedPtrFieldBase>(message, field)
1371               ->RemoveLast<GenericTypeHandler<Message> >();
1372         }
1373         break;
1374     }
1375   }
1376 }
1377 
1378 Message* Reflection::ReleaseLast(Message* message,
1379                                  const FieldDescriptor* field) const {
1380   USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE);
1381   CheckInvalidAccess(schema_, field);
1382 
1383   Message* released;
1384   if (field->is_extension()) {
1385     released = static_cast<Message*>(
1386         MutableExtensionSet(message)->ReleaseLast(field->number()));
1387   } else {
1388     if (IsMapFieldInApi(field)) {
1389       released = MutableRaw<MapFieldBase>(message, field)
1390                      ->MutableRepeatedField()
1391                      ->ReleaseLast<GenericTypeHandler<Message>>();
1392     } else {
1393       released = MutableRaw<RepeatedPtrFieldBase>(message, field)
1394                      ->ReleaseLast<GenericTypeHandler<Message>>();
1395     }
1396   }
1397 #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
1398   return MaybeForceCopy(message->GetArenaForAllocation(), released);
1399 #else   // PROTOBUF_FORCE_COPY_IN_RELEASE
1400   return released;
1401 #endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
1402 }
1403 
1404 Message* Reflection::UnsafeArenaReleaseLast(
1405     Message* message, const FieldDescriptor* field) const {
1406   USAGE_CHECK_ALL(UnsafeArenaReleaseLast, REPEATED, MESSAGE);
1407   CheckInvalidAccess(schema_, field);
1408 
1409   if (field->is_extension()) {
1410     return static_cast<Message*>(
1411         MutableExtensionSet(message)->UnsafeArenaReleaseLast(field->number()));
1412   } else {
1413     if (IsMapFieldInApi(field)) {
1414       return MutableRaw<MapFieldBase>(message, field)
1415           ->MutableRepeatedField()
1416           ->UnsafeArenaReleaseLast<GenericTypeHandler<Message>>();
1417     } else {
1418       return MutableRaw<RepeatedPtrFieldBase>(message, field)
1419           ->UnsafeArenaReleaseLast<GenericTypeHandler<Message>>();
1420     }
1421   }
1422 }
1423 
1424 void Reflection::SwapElements(Message* message, const FieldDescriptor* field,
1425                               int index1, int index2) const {
1426   USAGE_CHECK_MESSAGE_TYPE(Swap);
1427   USAGE_CHECK_REPEATED(Swap);
1428   CheckInvalidAccess(schema_, field);
1429 
1430   if (field->is_extension()) {
1431     MutableExtensionSet(message)->SwapElements(field->number(), index1, index2);
1432   } else {
1433     switch (field->cpp_type()) {
1434 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                 \
1435   case FieldDescriptor::CPPTYPE_##UPPERCASE:              \
1436     MutableRaw<RepeatedField<LOWERCASE> >(message, field) \
1437         ->SwapElements(index1, index2);                   \
1438     break
1439 
1440       HANDLE_TYPE(INT32, int32_t);
1441       HANDLE_TYPE(INT64, int64_t);
1442       HANDLE_TYPE(UINT32, uint32_t);
1443       HANDLE_TYPE(UINT64, uint64_t);
1444       HANDLE_TYPE(DOUBLE, double);
1445       HANDLE_TYPE(FLOAT, float);
1446       HANDLE_TYPE(BOOL, bool);
1447       HANDLE_TYPE(ENUM, int);
1448 #undef HANDLE_TYPE
1449 
1450       case FieldDescriptor::CPPTYPE_STRING:
1451       case FieldDescriptor::CPPTYPE_MESSAGE:
1452         if (IsMapFieldInApi(field)) {
1453           MutableRaw<MapFieldBase>(message, field)
1454               ->MutableRepeatedField()
1455               ->SwapElements(index1, index2);
1456         } else {
1457           MutableRaw<RepeatedPtrFieldBase>(message, field)
1458               ->SwapElements(index1, index2);
1459         }
1460         break;
1461     }
1462   }
1463 }
1464 
1465 namespace {
1466 // Comparison functor for sorting FieldDescriptors by field number.
1467 struct FieldNumberSorter {
1468   bool operator()(const FieldDescriptor* left,
1469                   const FieldDescriptor* right) const {
1470     return left->number() < right->number();
1471   }
1472 };
1473 
1474 bool IsIndexInHasBitSet(const uint32_t* has_bit_set, uint32_t has_bit_index) {
1475   GOOGLE_DCHECK_NE(has_bit_index, ~0u);
1476   return ((has_bit_set[has_bit_index / 32] >> (has_bit_index % 32)) &
1477           static_cast<uint32_t>(1)) != 0;
1478 }
1479 
1480 bool CreateUnknownEnumValues(const FileDescriptor* file) {
1481   return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
1482 }
1483 }  // namespace
1484 
1485 namespace internal {
1486 bool CreateUnknownEnumValues(const FieldDescriptor* field) {
1487   bool open_enum = false;
1488   return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || open_enum;
1489 }
1490 }  // namespace internal
1491 using internal::CreateUnknownEnumValues;
1492 
1493 void Reflection::ListFieldsMayFailOnStripped(
1494     const Message& message, bool should_fail,
1495     std::vector<const FieldDescriptor*>* output) const {
1496   output->clear();
1497 
1498   // Optimization:  The default instance never has any fields set.
1499   if (schema_.IsDefaultInstance(message)) return;
1500 
1501   // Optimization: Avoid calling GetHasBits() and HasOneofField() many times
1502   // within the field loop.  We allow this violation of ReflectionSchema
1503   // encapsulation because this function takes a noticeable about of CPU
1504   // fleetwide and properly allowing this optimization through public interfaces
1505   // seems more trouble than it is worth.
1506   const uint32_t* const has_bits =
1507       schema_.HasHasbits() ? GetHasBits(message) : nullptr;
1508   const uint32_t* const has_bits_indices = schema_.has_bit_indices_;
1509   output->reserve(descriptor_->field_count());
1510   const int last_non_weak_field_index = last_non_weak_field_index_;
1511   for (int i = 0; i <= last_non_weak_field_index; i++) {
1512     const FieldDescriptor* field = descriptor_->field(i);
1513     if (!should_fail && schema_.IsFieldStripped(field)) {
1514       continue;
1515     }
1516     if (field->is_repeated()) {
1517       if (FieldSize(message, field) > 0) {
1518         output->push_back(field);
1519       }
1520     } else {
1521       const OneofDescriptor* containing_oneof = field->containing_oneof();
1522       if (schema_.InRealOneof(field)) {
1523         const uint32_t* const oneof_case_array =
1524             GetConstPointerAtOffset<uint32_t>(&message,
1525                                               schema_.oneof_case_offset_);
1526         // Equivalent to: HasOneofField(message, field)
1527         if (static_cast<int64_t>(oneof_case_array[containing_oneof->index()]) ==
1528             field->number()) {
1529           output->push_back(field);
1530         }
1531       } else if (has_bits && has_bits_indices[i] != static_cast<uint32_t>(-1)) {
1532         CheckInvalidAccess(schema_, field);
1533         // Equivalent to: HasBit(message, field)
1534         if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) {
1535           output->push_back(field);
1536         }
1537       } else if (HasBit(message, field)) {  // Fall back on proto3-style HasBit.
1538         output->push_back(field);
1539       }
1540     }
1541   }
1542   if (schema_.HasExtensionSet()) {
1543     GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
1544                                           output);
1545   }
1546 
1547   // ListFields() must sort output by field number.
1548   std::sort(output->begin(), output->end(), FieldNumberSorter());
1549 }
1550 
1551 void Reflection::ListFields(const Message& message,
1552                             std::vector<const FieldDescriptor*>* output) const {
1553   ListFieldsMayFailOnStripped(message, true, output);
1554 }
1555 
1556 void Reflection::ListFieldsOmitStripped(
1557     const Message& message, std::vector<const FieldDescriptor*>* output) const {
1558   ListFieldsMayFailOnStripped(message, false, output);
1559 }
1560 
1561 // -------------------------------------------------------------------
1562 
1563 #undef DEFINE_PRIMITIVE_ACCESSORS
1564 #define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE)          \
1565   PASSTYPE Reflection::Get##TYPENAME(const Message& message,                   \
1566                                      const FieldDescriptor* field) const {     \
1567     USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE);                         \
1568     if (field->is_extension()) {                                               \
1569       return GetExtensionSet(message).Get##TYPENAME(                           \
1570           field->number(), field->default_value_##PASSTYPE());                 \
1571     } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { \
1572       return field->default_value_##PASSTYPE();                                \
1573     } else {                                                                   \
1574       return GetField<TYPE>(message, field);                                   \
1575     }                                                                          \
1576   }                                                                            \
1577                                                                                \
1578   void Reflection::Set##TYPENAME(                                              \
1579       Message* message, const FieldDescriptor* field, PASSTYPE value) const {  \
1580     USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE);                         \
1581     if (field->is_extension()) {                                               \
1582       return MutableExtensionSet(message)->Set##TYPENAME(                      \
1583           field->number(), field->type(), value, field);                       \
1584     } else {                                                                   \
1585       SetField<TYPE>(message, field, value);                                   \
1586     }                                                                          \
1587   }                                                                            \
1588                                                                                \
1589   PASSTYPE Reflection::GetRepeated##TYPENAME(                                  \
1590       const Message& message, const FieldDescriptor* field, int index) const { \
1591     USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE);                 \
1592     if (field->is_extension()) {                                               \
1593       return GetExtensionSet(message).GetRepeated##TYPENAME(field->number(),   \
1594                                                             index);            \
1595     } else {                                                                   \
1596       return GetRepeatedField<TYPE>(message, field, index);                    \
1597     }                                                                          \
1598   }                                                                            \
1599                                                                                \
1600   void Reflection::SetRepeated##TYPENAME(Message* message,                     \
1601                                          const FieldDescriptor* field,         \
1602                                          int index, PASSTYPE value) const {    \
1603     USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE);                 \
1604     if (field->is_extension()) {                                               \
1605       MutableExtensionSet(message)->SetRepeated##TYPENAME(field->number(),     \
1606                                                           index, value);       \
1607     } else {                                                                   \
1608       SetRepeatedField<TYPE>(message, field, index, value);                    \
1609     }                                                                          \
1610   }                                                                            \
1611                                                                                \
1612   void Reflection::Add##TYPENAME(                                              \
1613       Message* message, const FieldDescriptor* field, PASSTYPE value) const {  \
1614     USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE);                         \
1615     if (field->is_extension()) {                                               \
1616       MutableExtensionSet(message)->Add##TYPENAME(                             \
1617           field->number(), field->type(), field->options().packed(), value,    \
1618           field);                                                              \
1619     } else {                                                                   \
1620       AddField<TYPE>(message, field, value);                                   \
1621     }                                                                          \
1622   }
1623 
1624 DEFINE_PRIMITIVE_ACCESSORS(Int32, int32_t, int32_t, INT32)
1625 DEFINE_PRIMITIVE_ACCESSORS(Int64, int64_t, int64_t, INT64)
1626 DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32_t, uint32_t, UINT32)
1627 DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64_t, uint64_t, UINT64)
1628 DEFINE_PRIMITIVE_ACCESSORS(Float, float, float, FLOAT)
1629 DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE)
1630 DEFINE_PRIMITIVE_ACCESSORS(Bool, bool, bool, BOOL)
1631 #undef DEFINE_PRIMITIVE_ACCESSORS
1632 
1633 // -------------------------------------------------------------------
1634 
1635 std::string Reflection::GetString(const Message& message,
1636                                   const FieldDescriptor* field) const {
1637   USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
1638   if (field->is_extension()) {
1639     return GetExtensionSet(message).GetString(field->number(),
1640                                               field->default_value_string());
1641   } else {
1642     if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1643       return field->default_value_string();
1644     }
1645     switch (field->options().ctype()) {
1646       default:  // TODO(kenton):  Support other string reps.
1647       case FieldOptions::STRING:
1648         if (IsInlined(field)) {
1649           return GetField<InlinedStringField>(message, field).GetNoArena();
1650         } else {
1651           const auto& str = GetField<ArenaStringPtr>(message, field);
1652           return str.IsDefault() ? field->default_value_string() : str.Get();
1653         }
1654     }
1655   }
1656 }
1657 
1658 const std::string& Reflection::GetStringReference(const Message& message,
1659                                                   const FieldDescriptor* field,
1660                                                   std::string* scratch) const {
1661   (void)scratch;  // Parameter is used by Google-internal code.
1662   USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
1663   if (field->is_extension()) {
1664     return GetExtensionSet(message).GetString(field->number(),
1665                                               field->default_value_string());
1666   } else {
1667     if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1668       return field->default_value_string();
1669     }
1670     switch (field->options().ctype()) {
1671       default:  // TODO(kenton):  Support other string reps.
1672       case FieldOptions::STRING:
1673         if (IsInlined(field)) {
1674           return GetField<InlinedStringField>(message, field).GetNoArena();
1675         } else {
1676           const auto& str = GetField<ArenaStringPtr>(message, field);
1677           return str.IsDefault() ? field->default_value_string() : str.Get();
1678         }
1679     }
1680   }
1681 }
1682 
1683 
1684 void Reflection::SetString(Message* message, const FieldDescriptor* field,
1685                            std::string value) const {
1686   USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
1687   if (field->is_extension()) {
1688     return MutableExtensionSet(message)->SetString(
1689         field->number(), field->type(), std::move(value), field);
1690   } else {
1691     switch (field->options().ctype()) {
1692       default:  // TODO(kenton):  Support other string reps.
1693       case FieldOptions::STRING: {
1694         if (IsInlined(field)) {
1695           const uint32_t index = schema_.InlinedStringIndex(field);
1696           GOOGLE_DCHECK_GT(index, 0);
1697           uint32_t* states =
1698               &MutableInlinedStringDonatedArray(message)[index / 32];
1699           uint32_t mask = ~(static_cast<uint32_t>(1) << (index % 32));
1700           MutableField<InlinedStringField>(message, field)
1701               ->Set(value, message->GetArenaForAllocation(),
1702                     IsInlinedStringDonated(*message, field), states, mask,
1703                     message);
1704           break;
1705         }
1706 
1707         // Oneof string fields are never set as a default instance.
1708         // We just need to pass some arbitrary default string to make it work.
1709         // This allows us to not have the real default accessible from
1710         // reflection.
1711         if (schema_.InRealOneof(field) && !HasOneofField(*message, field)) {
1712           ClearOneof(message, field->containing_oneof());
1713           MutableField<ArenaStringPtr>(message, field)->InitDefault();
1714         }
1715         MutableField<ArenaStringPtr>(message, field)
1716             ->Set(std::move(value), message->GetArenaForAllocation());
1717         break;
1718       }
1719     }
1720   }
1721 }
1722 
1723 
1724 std::string Reflection::GetRepeatedString(const Message& message,
1725                                           const FieldDescriptor* field,
1726                                           int index) const {
1727   USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
1728   if (field->is_extension()) {
1729     return GetExtensionSet(message).GetRepeatedString(field->number(), index);
1730   } else {
1731     switch (field->options().ctype()) {
1732       default:  // TODO(kenton):  Support other string reps.
1733       case FieldOptions::STRING:
1734         return GetRepeatedPtrField<std::string>(message, field, index);
1735     }
1736   }
1737 }
1738 
1739 const std::string& Reflection::GetRepeatedStringReference(
1740     const Message& message, const FieldDescriptor* field, int index,
1741     std::string* scratch) const {
1742   (void)scratch;  // Parameter is used by Google-internal code.
1743   USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
1744   if (field->is_extension()) {
1745     return GetExtensionSet(message).GetRepeatedString(field->number(), index);
1746   } else {
1747     switch (field->options().ctype()) {
1748       default:  // TODO(kenton):  Support other string reps.
1749       case FieldOptions::STRING:
1750         return GetRepeatedPtrField<std::string>(message, field, index);
1751     }
1752   }
1753 }
1754 
1755 
1756 void Reflection::SetRepeatedString(Message* message,
1757                                    const FieldDescriptor* field, int index,
1758                                    std::string value) const {
1759   USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
1760   if (field->is_extension()) {
1761     MutableExtensionSet(message)->SetRepeatedString(field->number(), index,
1762                                                     std::move(value));
1763   } else {
1764     switch (field->options().ctype()) {
1765       default:  // TODO(kenton):  Support other string reps.
1766       case FieldOptions::STRING:
1767         MutableRepeatedField<std::string>(message, field, index)
1768             ->assign(std::move(value));
1769         break;
1770     }
1771   }
1772 }
1773 
1774 
1775 void Reflection::AddString(Message* message, const FieldDescriptor* field,
1776                            std::string value) const {
1777   USAGE_CHECK_ALL(AddString, REPEATED, STRING);
1778   if (field->is_extension()) {
1779     MutableExtensionSet(message)->AddString(field->number(), field->type(),
1780                                             std::move(value), field);
1781   } else {
1782     switch (field->options().ctype()) {
1783       default:  // TODO(kenton):  Support other string reps.
1784       case FieldOptions::STRING:
1785         AddField<std::string>(message, field)->assign(std::move(value));
1786         break;
1787     }
1788   }
1789 }
1790 
1791 
1792 // -------------------------------------------------------------------
1793 
1794 const EnumValueDescriptor* Reflection::GetEnum(
1795     const Message& message, const FieldDescriptor* field) const {
1796   // Usage checked by GetEnumValue.
1797   int value = GetEnumValue(message, field);
1798   return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1799 }
1800 
1801 int Reflection::GetEnumValue(const Message& message,
1802                              const FieldDescriptor* field) const {
1803   USAGE_CHECK_ALL(GetEnumValue, SINGULAR, ENUM);
1804 
1805   int32_t value;
1806   if (field->is_extension()) {
1807     value = GetExtensionSet(message).GetEnum(
1808         field->number(), field->default_value_enum()->number());
1809   } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1810     value = field->default_value_enum()->number();
1811   } else {
1812     value = GetField<int>(message, field);
1813   }
1814   return value;
1815 }
1816 
1817 void Reflection::SetEnum(Message* message, const FieldDescriptor* field,
1818                          const EnumValueDescriptor* value) const {
1819   // Usage checked by SetEnumValue.
1820   USAGE_CHECK_ENUM_VALUE(SetEnum);
1821   SetEnumValueInternal(message, field, value->number());
1822 }
1823 
1824 void Reflection::SetEnumValue(Message* message, const FieldDescriptor* field,
1825                               int value) const {
1826   USAGE_CHECK_ALL(SetEnumValue, SINGULAR, ENUM);
1827   if (!CreateUnknownEnumValues(field)) {
1828     // Check that the value is valid if we don't support direct storage of
1829     // unknown enum values.
1830     const EnumValueDescriptor* value_desc =
1831         field->enum_type()->FindValueByNumber(value);
1832     if (value_desc == nullptr) {
1833       MutableUnknownFields(message)->AddVarint(field->number(), value);
1834       return;
1835     }
1836   }
1837   SetEnumValueInternal(message, field, value);
1838 }
1839 
1840 void Reflection::SetEnumValueInternal(Message* message,
1841                                       const FieldDescriptor* field,
1842                                       int value) const {
1843   if (field->is_extension()) {
1844     MutableExtensionSet(message)->SetEnum(field->number(), field->type(), value,
1845                                           field);
1846   } else {
1847     SetField<int>(message, field, value);
1848   }
1849 }
1850 
1851 const EnumValueDescriptor* Reflection::GetRepeatedEnum(
1852     const Message& message, const FieldDescriptor* field, int index) const {
1853   // Usage checked by GetRepeatedEnumValue.
1854   int value = GetRepeatedEnumValue(message, field, index);
1855   return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
1856 }
1857 
1858 int Reflection::GetRepeatedEnumValue(const Message& message,
1859                                      const FieldDescriptor* field,
1860                                      int index) const {
1861   USAGE_CHECK_ALL(GetRepeatedEnumValue, REPEATED, ENUM);
1862 
1863   int value;
1864   if (field->is_extension()) {
1865     value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
1866   } else {
1867     value = GetRepeatedField<int>(message, field, index);
1868   }
1869   return value;
1870 }
1871 
1872 void Reflection::SetRepeatedEnum(Message* message, const FieldDescriptor* field,
1873                                  int index,
1874                                  const EnumValueDescriptor* value) const {
1875   // Usage checked by SetRepeatedEnumValue.
1876   USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
1877   SetRepeatedEnumValueInternal(message, field, index, value->number());
1878 }
1879 
1880 void Reflection::SetRepeatedEnumValue(Message* message,
1881                                       const FieldDescriptor* field, int index,
1882                                       int value) const {
1883   USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
1884   if (!CreateUnknownEnumValues(field)) {
1885     // Check that the value is valid if we don't support direct storage of
1886     // unknown enum values.
1887     const EnumValueDescriptor* value_desc =
1888         field->enum_type()->FindValueByNumber(value);
1889     if (value_desc == nullptr) {
1890       MutableUnknownFields(message)->AddVarint(field->number(), value);
1891       return;
1892     }
1893   }
1894   SetRepeatedEnumValueInternal(message, field, index, value);
1895 }
1896 
1897 void Reflection::SetRepeatedEnumValueInternal(Message* message,
1898                                               const FieldDescriptor* field,
1899                                               int index, int value) const {
1900   if (field->is_extension()) {
1901     MutableExtensionSet(message)->SetRepeatedEnum(field->number(), index,
1902                                                   value);
1903   } else {
1904     SetRepeatedField<int>(message, field, index, value);
1905   }
1906 }
1907 
1908 void Reflection::AddEnum(Message* message, const FieldDescriptor* field,
1909                          const EnumValueDescriptor* value) const {
1910   // Usage checked by AddEnumValue.
1911   USAGE_CHECK_ENUM_VALUE(AddEnum);
1912   AddEnumValueInternal(message, field, value->number());
1913 }
1914 
1915 void Reflection::AddEnumValue(Message* message, const FieldDescriptor* field,
1916                               int value) const {
1917   USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
1918   if (!CreateUnknownEnumValues(field)) {
1919     // Check that the value is valid if we don't support direct storage of
1920     // unknown enum values.
1921     const EnumValueDescriptor* value_desc =
1922         field->enum_type()->FindValueByNumber(value);
1923     if (value_desc == nullptr) {
1924       MutableUnknownFields(message)->AddVarint(field->number(), value);
1925       return;
1926     }
1927   }
1928   AddEnumValueInternal(message, field, value);
1929 }
1930 
1931 void Reflection::AddEnumValueInternal(Message* message,
1932                                       const FieldDescriptor* field,
1933                                       int value) const {
1934   if (field->is_extension()) {
1935     MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
1936                                           field->options().packed(), value,
1937                                           field);
1938   } else {
1939     AddField<int>(message, field, value);
1940   }
1941 }
1942 
1943 // -------------------------------------------------------------------
1944 
1945 const Message* Reflection::GetDefaultMessageInstance(
1946     const FieldDescriptor* field) const {
1947   // If we are using the generated factory, we cache the prototype in the field
1948   // descriptor for faster access.
1949   // The default instances of generated messages are not cross-linked, which
1950   // means they contain null pointers on their message fields and can't be used
1951   // to get the default of submessages.
1952   if (message_factory_ == MessageFactory::generated_factory()) {
1953     auto& ptr = field->default_generated_instance_;
1954     auto* res = ptr.load(std::memory_order_acquire);
1955     if (res == nullptr) {
1956       // First time asking for this field's default. Load it and cache it.
1957       res = message_factory_->GetPrototype(field->message_type());
1958       ptr.store(res, std::memory_order_release);
1959     }
1960     return res;
1961   }
1962 
1963   // For other factories, we try the default's object field.
1964   // In particular, the DynamicMessageFactory will cross link the default
1965   // instances to allow for this. But only do this for real fields.
1966   // This is an optimization to avoid going to GetPrototype() below, as that
1967   // requires a lock and a map lookup.
1968   if (!field->is_extension() && !field->options().weak() &&
1969       !IsLazyField(field) && !schema_.InRealOneof(field)) {
1970     auto* res = DefaultRaw<const Message*>(field);
1971     if (res != nullptr) {
1972       return res;
1973     }
1974   }
1975   // Otherwise, just go to the factory.
1976   return message_factory_->GetPrototype(field->message_type());
1977 }
1978 
1979 const Message& Reflection::GetMessage(const Message& message,
1980                                       const FieldDescriptor* field,
1981                                       MessageFactory* factory) const {
1982   USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
1983   CheckInvalidAccess(schema_, field);
1984 
1985   if (factory == nullptr) factory = message_factory_;
1986 
1987   if (field->is_extension()) {
1988     return static_cast<const Message&>(GetExtensionSet(message).GetMessage(
1989         field->number(), field->message_type(), factory));
1990   } else {
1991     if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1992       return *GetDefaultMessageInstance(field);
1993     }
1994     const Message* result = GetRaw<const Message*>(message, field);
1995     if (result == nullptr) {
1996       result = GetDefaultMessageInstance(field);
1997     }
1998     return *result;
1999   }
2000 }
2001 
2002 Message* Reflection::MutableMessage(Message* message,
2003                                     const FieldDescriptor* field,
2004                                     MessageFactory* factory) const {
2005   USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
2006   CheckInvalidAccess(schema_, field);
2007 
2008   if (factory == nullptr) factory = message_factory_;
2009 
2010   if (field->is_extension()) {
2011     return static_cast<Message*>(
2012         MutableExtensionSet(message)->MutableMessage(field, factory));
2013   } else {
2014     Message* result;
2015 
2016     Message** result_holder = MutableRaw<Message*>(message, field);
2017 
2018     if (schema_.InRealOneof(field)) {
2019       if (!HasOneofField(*message, field)) {
2020         ClearOneof(message, field->containing_oneof());
2021         result_holder = MutableField<Message*>(message, field);
2022         const Message* default_message = GetDefaultMessageInstance(field);
2023         *result_holder = default_message->New(message->GetArenaForAllocation());
2024       }
2025     } else {
2026       SetBit(message, field);
2027     }
2028 
2029     if (*result_holder == nullptr) {
2030       const Message* default_message = GetDefaultMessageInstance(field);
2031       *result_holder = default_message->New(message->GetArenaForAllocation());
2032     }
2033     result = *result_holder;
2034     return result;
2035   }
2036 }
2037 
2038 void Reflection::UnsafeArenaSetAllocatedMessage(
2039     Message* message, Message* sub_message,
2040     const FieldDescriptor* field) const {
2041   USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
2042   CheckInvalidAccess(schema_, field);
2043 
2044 
2045   if (field->is_extension()) {
2046     MutableExtensionSet(message)->UnsafeArenaSetAllocatedMessage(
2047         field->number(), field->type(), field, sub_message);
2048   } else {
2049     if (schema_.InRealOneof(field)) {
2050       if (sub_message == nullptr) {
2051         ClearOneof(message, field->containing_oneof());
2052         return;
2053       }
2054         ClearOneof(message, field->containing_oneof());
2055         *MutableRaw<Message*>(message, field) = sub_message;
2056       SetOneofCase(message, field);
2057       return;
2058     }
2059 
2060     if (sub_message == nullptr) {
2061       ClearBit(message, field);
2062     } else {
2063       SetBit(message, field);
2064     }
2065     Message** sub_message_holder = MutableRaw<Message*>(message, field);
2066     if (message->GetArenaForAllocation() == nullptr) {
2067       delete *sub_message_holder;
2068     }
2069     *sub_message_holder = sub_message;
2070   }
2071 }
2072 
2073 void Reflection::SetAllocatedMessage(Message* message, Message* sub_message,
2074                                      const FieldDescriptor* field) const {
2075   GOOGLE_DCHECK(sub_message == nullptr || sub_message->GetOwningArena() == nullptr ||
2076          sub_message->GetOwningArena() == message->GetArenaForAllocation());
2077   CheckInvalidAccess(schema_, field);
2078 
2079   // If message and sub-message are in different memory ownership domains
2080   // (different arenas, or one is on heap and one is not), then we may need to
2081   // do a copy.
2082   if (sub_message != nullptr &&
2083       sub_message->GetOwningArena() != message->GetArenaForAllocation()) {
2084     if (sub_message->GetOwningArena() == nullptr &&
2085         message->GetArenaForAllocation() != nullptr) {
2086       // Case 1: parent is on an arena and child is heap-allocated. We can add
2087       // the child to the arena's Own() list to free on arena destruction, then
2088       // set our pointer.
2089       message->GetArenaForAllocation()->Own(sub_message);
2090       UnsafeArenaSetAllocatedMessage(message, sub_message, field);
2091     } else {
2092       // Case 2: all other cases. We need to make a copy. MutableMessage() will
2093       // either get the existing message object, or instantiate a new one as
2094       // appropriate w.r.t. our arena.
2095       Message* sub_message_copy = MutableMessage(message, field);
2096       sub_message_copy->CopyFrom(*sub_message);
2097     }
2098   } else {
2099     // Same memory ownership domains.
2100     UnsafeArenaSetAllocatedMessage(message, sub_message, field);
2101   }
2102 }
2103 
2104 Message* Reflection::UnsafeArenaReleaseMessage(Message* message,
2105                                                const FieldDescriptor* field,
2106                                                MessageFactory* factory) const {
2107   USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
2108   CheckInvalidAccess(schema_, field);
2109 
2110   if (factory == nullptr) factory = message_factory_;
2111 
2112   if (field->is_extension()) {
2113     return static_cast<Message*>(
2114         MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field,
2115                                                                 factory));
2116   } else {
2117     if (!(field->is_repeated() || schema_.InRealOneof(field))) {
2118       ClearBit(message, field);
2119     }
2120     if (schema_.InRealOneof(field)) {
2121       if (HasOneofField(*message, field)) {
2122         *MutableOneofCase(message, field->containing_oneof()) = 0;
2123       } else {
2124         return nullptr;
2125       }
2126     }
2127     Message** result = MutableRaw<Message*>(message, field);
2128     Message* ret = *result;
2129     *result = nullptr;
2130     return ret;
2131   }
2132 }
2133 
2134 Message* Reflection::ReleaseMessage(Message* message,
2135                                     const FieldDescriptor* field,
2136                                     MessageFactory* factory) const {
2137   CheckInvalidAccess(schema_, field);
2138 
2139   Message* released = UnsafeArenaReleaseMessage(message, field, factory);
2140 #ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
2141   released = MaybeForceCopy(message->GetArenaForAllocation(), released);
2142 #endif  // PROTOBUF_FORCE_COPY_IN_RELEASE
2143   if (message->GetArenaForAllocation() != nullptr && released != nullptr) {
2144     Message* copy_from_arena = released->New();
2145     copy_from_arena->CopyFrom(*released);
2146     released = copy_from_arena;
2147   }
2148   return released;
2149 }
2150 
2151 const Message& Reflection::GetRepeatedMessage(const Message& message,
2152                                               const FieldDescriptor* field,
2153                                               int index) const {
2154   USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
2155   CheckInvalidAccess(schema_, field);
2156 
2157   if (field->is_extension()) {
2158     return static_cast<const Message&>(
2159         GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
2160   } else {
2161     if (IsMapFieldInApi(field)) {
2162       return GetRaw<MapFieldBase>(message, field)
2163           .GetRepeatedField()
2164           .Get<GenericTypeHandler<Message> >(index);
2165     } else {
2166       return GetRaw<RepeatedPtrFieldBase>(message, field)
2167           .Get<GenericTypeHandler<Message> >(index);
2168     }
2169   }
2170 }
2171 
2172 Message* Reflection::MutableRepeatedMessage(Message* message,
2173                                             const FieldDescriptor* field,
2174                                             int index) const {
2175   USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
2176   CheckInvalidAccess(schema_, field);
2177 
2178   if (field->is_extension()) {
2179     return static_cast<Message*>(
2180         MutableExtensionSet(message)->MutableRepeatedMessage(field->number(),
2181                                                              index));
2182   } else {
2183     if (IsMapFieldInApi(field)) {
2184       return MutableRaw<MapFieldBase>(message, field)
2185           ->MutableRepeatedField()
2186           ->Mutable<GenericTypeHandler<Message> >(index);
2187     } else {
2188       return MutableRaw<RepeatedPtrFieldBase>(message, field)
2189           ->Mutable<GenericTypeHandler<Message> >(index);
2190     }
2191   }
2192 }
2193 
2194 Message* Reflection::AddMessage(Message* message, const FieldDescriptor* field,
2195                                 MessageFactory* factory) const {
2196   USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
2197   CheckInvalidAccess(schema_, field);
2198 
2199   if (factory == nullptr) factory = message_factory_;
2200 
2201   if (field->is_extension()) {
2202     return static_cast<Message*>(
2203         MutableExtensionSet(message)->AddMessage(field, factory));
2204   } else {
2205     Message* result = nullptr;
2206 
2207     // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
2208     // know how to allocate one.
2209     RepeatedPtrFieldBase* repeated = nullptr;
2210     if (IsMapFieldInApi(field)) {
2211       repeated =
2212           MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
2213     } else {
2214       repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
2215     }
2216     result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
2217     if (result == nullptr) {
2218       // We must allocate a new object.
2219       const Message* prototype;
2220       if (repeated->size() == 0) {
2221         prototype = factory->GetPrototype(field->message_type());
2222       } else {
2223         prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
2224       }
2225       result = prototype->New(message->GetArenaForAllocation());
2226       // We can guarantee here that repeated and result are either both heap
2227       // allocated or arena owned. So it is safe to call the unsafe version
2228       // of AddAllocated.
2229       repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message> >(result);
2230     }
2231 
2232     return result;
2233   }
2234 }
2235 
2236 void Reflection::AddAllocatedMessage(Message* message,
2237                                      const FieldDescriptor* field,
2238                                      Message* new_entry) const {
2239   USAGE_CHECK_ALL(AddAllocatedMessage, REPEATED, MESSAGE);
2240   CheckInvalidAccess(schema_, field);
2241 
2242   if (field->is_extension()) {
2243     MutableExtensionSet(message)->AddAllocatedMessage(field, new_entry);
2244   } else {
2245     RepeatedPtrFieldBase* repeated = nullptr;
2246     if (IsMapFieldInApi(field)) {
2247       repeated =
2248           MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
2249     } else {
2250       repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
2251     }
2252     repeated->AddAllocated<GenericTypeHandler<Message> >(new_entry);
2253   }
2254 }
2255 
2256 void Reflection::UnsafeArenaAddAllocatedMessage(Message* message,
2257                                                 const FieldDescriptor* field,
2258                                                 Message* new_entry) const {
2259   USAGE_CHECK_ALL(UnsafeArenaAddAllocatedMessage, REPEATED, MESSAGE);
2260   CheckInvalidAccess(schema_, field);
2261 
2262   if (field->is_extension()) {
2263     MutableExtensionSet(message)->UnsafeArenaAddAllocatedMessage(field,
2264                                                                  new_entry);
2265   } else {
2266     RepeatedPtrFieldBase* repeated = nullptr;
2267     if (IsMapFieldInApi(field)) {
2268       repeated =
2269           MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
2270     } else {
2271       repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
2272     }
2273     repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message>>(new_entry);
2274   }
2275 }
2276 
2277 void* Reflection::MutableRawRepeatedField(Message* message,
2278                                           const FieldDescriptor* field,
2279                                           FieldDescriptor::CppType cpptype,
2280                                           int ctype,
2281                                           const Descriptor* desc) const {
2282   (void)ctype;  // Parameter is used by Google-internal code.
2283   USAGE_CHECK_REPEATED("MutableRawRepeatedField");
2284   CheckInvalidAccess(schema_, field);
2285 
2286   if (field->cpp_type() != cpptype &&
2287       (field->cpp_type() != FieldDescriptor::CPPTYPE_ENUM ||
2288        cpptype != FieldDescriptor::CPPTYPE_INT32))
2289     ReportReflectionUsageTypeError(descriptor_, field,
2290                                    "MutableRawRepeatedField", cpptype);
2291   if (desc != nullptr)
2292     GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
2293   if (field->is_extension()) {
2294     return MutableExtensionSet(message)->MutableRawRepeatedField(
2295         field->number(), field->type(), field->is_packed(), field);
2296   } else {
2297     // Trigger transform for MapField
2298     if (IsMapFieldInApi(field)) {
2299       return MutableRawNonOneof<MapFieldBase>(message, field)
2300           ->MutableRepeatedField();
2301     }
2302     return MutableRawNonOneof<void>(message, field);
2303   }
2304 }
2305 
2306 const void* Reflection::GetRawRepeatedField(const Message& message,
2307                                             const FieldDescriptor* field,
2308                                             FieldDescriptor::CppType cpptype,
2309                                             int ctype,
2310                                             const Descriptor* desc) const {
2311   USAGE_CHECK_REPEATED("GetRawRepeatedField");
2312   if (field->cpp_type() != cpptype)
2313     ReportReflectionUsageTypeError(descriptor_, field, "GetRawRepeatedField",
2314                                    cpptype);
2315   if (ctype >= 0)
2316     GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
2317   if (desc != nullptr)
2318     GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
2319   if (field->is_extension()) {
2320     // Should use extension_set::GetRawRepeatedField. However, the required
2321     // parameter "default repeated value" is not very easy to get here.
2322     // Map is not supported in extensions, it is acceptable to use
2323     // extension_set::MutableRawRepeatedField which does not change the message.
2324     return MutableExtensionSet(const_cast<Message*>(&message))
2325         ->MutableRawRepeatedField(field->number(), field->type(),
2326                                   field->is_packed(), field);
2327   } else {
2328     // Trigger transform for MapField
2329     if (IsMapFieldInApi(field)) {
2330       return &(GetRawNonOneof<MapFieldBase>(message, field).GetRepeatedField());
2331     }
2332     return &GetRawNonOneof<char>(message, field);
2333   }
2334 }
2335 
2336 const FieldDescriptor* Reflection::GetOneofFieldDescriptor(
2337     const Message& message, const OneofDescriptor* oneof_descriptor) const {
2338   if (oneof_descriptor->is_synthetic()) {
2339     const FieldDescriptor* field = oneof_descriptor->field(0);
2340     return HasField(message, field) ? field : nullptr;
2341   }
2342   uint32_t field_number = GetOneofCase(message, oneof_descriptor);
2343   if (field_number == 0) {
2344     return nullptr;
2345   }
2346   return descriptor_->FindFieldByNumber(field_number);
2347 }
2348 
2349 bool Reflection::ContainsMapKey(const Message& message,
2350                                 const FieldDescriptor* field,
2351                                 const MapKey& key) const {
2352   USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue",
2353               "Field is not a map field.");
2354   return GetRaw<MapFieldBase>(message, field).ContainsMapKey(key);
2355 }
2356 
2357 bool Reflection::InsertOrLookupMapValue(Message* message,
2358                                         const FieldDescriptor* field,
2359                                         const MapKey& key,
2360                                         MapValueRef* val) const {
2361   USAGE_CHECK(IsMapFieldInApi(field), "InsertOrLookupMapValue",
2362               "Field is not a map field.");
2363   val->SetType(field->message_type()->map_value()->cpp_type());
2364   return MutableRaw<MapFieldBase>(message, field)
2365       ->InsertOrLookupMapValue(key, val);
2366 }
2367 
2368 bool Reflection::LookupMapValue(const Message& message,
2369                                 const FieldDescriptor* field, const MapKey& key,
2370                                 MapValueConstRef* val) const {
2371   USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue",
2372               "Field is not a map field.");
2373   val->SetType(field->message_type()->map_value()->cpp_type());
2374   return GetRaw<MapFieldBase>(message, field).LookupMapValue(key, val);
2375 }
2376 
2377 bool Reflection::DeleteMapValue(Message* message, const FieldDescriptor* field,
2378                                 const MapKey& key) const {
2379   USAGE_CHECK(IsMapFieldInApi(field), "DeleteMapValue",
2380               "Field is not a map field.");
2381   return MutableRaw<MapFieldBase>(message, field)->DeleteMapValue(key);
2382 }
2383 
2384 MapIterator Reflection::MapBegin(Message* message,
2385                                  const FieldDescriptor* field) const {
2386   USAGE_CHECK(IsMapFieldInApi(field), "MapBegin", "Field is not a map field.");
2387   MapIterator iter(message, field);
2388   GetRaw<MapFieldBase>(*message, field).MapBegin(&iter);
2389   return iter;
2390 }
2391 
2392 MapIterator Reflection::MapEnd(Message* message,
2393                                const FieldDescriptor* field) const {
2394   USAGE_CHECK(IsMapFieldInApi(field), "MapEnd", "Field is not a map field.");
2395   MapIterator iter(message, field);
2396   GetRaw<MapFieldBase>(*message, field).MapEnd(&iter);
2397   return iter;
2398 }
2399 
2400 int Reflection::MapSize(const Message& message,
2401                         const FieldDescriptor* field) const {
2402   USAGE_CHECK(IsMapFieldInApi(field), "MapSize", "Field is not a map field.");
2403   return GetRaw<MapFieldBase>(message, field).size();
2404 }
2405 
2406 // -----------------------------------------------------------------------------
2407 
2408 const FieldDescriptor* Reflection::FindKnownExtensionByName(
2409     const std::string& name) const {
2410   if (!schema_.HasExtensionSet()) return nullptr;
2411   return descriptor_pool_->FindExtensionByPrintableName(descriptor_, name);
2412 }
2413 
2414 const FieldDescriptor* Reflection::FindKnownExtensionByNumber(
2415     int number) const {
2416   if (!schema_.HasExtensionSet()) return nullptr;
2417   return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
2418 }
2419 
2420 bool Reflection::SupportsUnknownEnumValues() const {
2421   return CreateUnknownEnumValues(descriptor_->file());
2422 }
2423 
2424 // ===================================================================
2425 // Some private helpers.
2426 
2427 // These simple template accessors obtain pointers (or references) to
2428 // the given field.
2429 
2430 template <class Type>
2431 const Type& Reflection::GetRawNonOneof(const Message& message,
2432                                        const FieldDescriptor* field) const {
2433   return GetConstRefAtOffset<Type>(message,
2434                                    schema_.GetFieldOffsetNonOneof(field));
2435 }
2436 
2437 template <class Type>
2438 Type* Reflection::MutableRawNonOneof(Message* message,
2439                                      const FieldDescriptor* field) const {
2440   return GetPointerAtOffset<Type>(message,
2441                                   schema_.GetFieldOffsetNonOneof(field));
2442 }
2443 
2444 template <typename Type>
2445 Type* Reflection::MutableRaw(Message* message,
2446                              const FieldDescriptor* field) const {
2447   return GetPointerAtOffset<Type>(message, schema_.GetFieldOffset(field));
2448 }
2449 
2450 const uint32_t* Reflection::GetHasBits(const Message& message) const {
2451   GOOGLE_DCHECK(schema_.HasHasbits());
2452   return &GetConstRefAtOffset<uint32_t>(message, schema_.HasBitsOffset());
2453 }
2454 
2455 uint32_t* Reflection::MutableHasBits(Message* message) const {
2456   GOOGLE_DCHECK(schema_.HasHasbits());
2457   return GetPointerAtOffset<uint32_t>(message, schema_.HasBitsOffset());
2458 }
2459 
2460 uint32_t* Reflection::MutableOneofCase(
2461     Message* message, const OneofDescriptor* oneof_descriptor) const {
2462   GOOGLE_DCHECK(!oneof_descriptor->is_synthetic());
2463   return GetPointerAtOffset<uint32_t>(
2464       message, schema_.GetOneofCaseOffset(oneof_descriptor));
2465 }
2466 
2467 const ExtensionSet& Reflection::GetExtensionSet(const Message& message) const {
2468   return GetConstRefAtOffset<ExtensionSet>(message,
2469                                            schema_.GetExtensionSetOffset());
2470 }
2471 
2472 ExtensionSet* Reflection::MutableExtensionSet(Message* message) const {
2473   return GetPointerAtOffset<ExtensionSet>(message,
2474                                           schema_.GetExtensionSetOffset());
2475 }
2476 
2477 const InternalMetadata& Reflection::GetInternalMetadata(
2478     const Message& message) const {
2479   return GetConstRefAtOffset<InternalMetadata>(message,
2480                                                schema_.GetMetadataOffset());
2481 }
2482 
2483 InternalMetadata* Reflection::MutableInternalMetadata(Message* message) const {
2484   return GetPointerAtOffset<InternalMetadata>(message,
2485                                               schema_.GetMetadataOffset());
2486 }
2487 
2488 const uint32_t* Reflection::GetInlinedStringDonatedArray(
2489     const Message& message) const {
2490   GOOGLE_DCHECK(schema_.HasInlinedString());
2491   return &GetConstRefAtOffset<uint32_t>(message,
2492                                         schema_.InlinedStringDonatedOffset());
2493 }
2494 
2495 uint32_t* Reflection::MutableInlinedStringDonatedArray(Message* message) const {
2496   GOOGLE_DCHECK(schema_.HasInlinedString());
2497   return GetPointerAtOffset<uint32_t>(message,
2498                                       schema_.InlinedStringDonatedOffset());
2499 }
2500 
2501 // Simple accessors for manipulating _inlined_string_donated_;
2502 bool Reflection::IsInlinedStringDonated(const Message& message,
2503                                         const FieldDescriptor* field) const {
2504   uint32_t index = schema_.InlinedStringIndex(field);
2505   GOOGLE_DCHECK_GT(index, 0);
2506   return IsIndexInHasBitSet(GetInlinedStringDonatedArray(message), index);
2507 }
2508 
2509 inline void SetInlinedStringDonated(uint32_t index, uint32_t* array) {
2510   array[index / 32] |= (static_cast<uint32_t>(1) << (index % 32));
2511 }
2512 
2513 inline void ClearInlinedStringDonated(uint32_t index, uint32_t* array) {
2514   array[index / 32] &= ~(static_cast<uint32_t>(1) << (index % 32));
2515 }
2516 
2517 void Reflection::SwapInlinedStringDonated(Message* lhs, Message* rhs,
2518                                           const FieldDescriptor* field) const {
2519   Arena* lhs_arena = lhs->GetArenaForAllocation();
2520   Arena* rhs_arena = rhs->GetArenaForAllocation();
2521   // If arenas differ, inined string fields are swapped by copying values.
2522   // Donation status should not be swapped.
2523   if (lhs_arena != rhs_arena) {
2524     return;
2525   }
2526   bool lhs_donated = IsInlinedStringDonated(*lhs, field);
2527   bool rhs_donated = IsInlinedStringDonated(*rhs, field);
2528   if (lhs_donated == rhs_donated) {
2529     return;
2530   }
2531   // If one is undonated, both must have already registered ArenaDtor.
2532   uint32_t* lhs_array = MutableInlinedStringDonatedArray(lhs);
2533   uint32_t* rhs_array = MutableInlinedStringDonatedArray(rhs);
2534   GOOGLE_CHECK_EQ(lhs_array[0] & 0x1u, 0u);
2535   GOOGLE_CHECK_EQ(rhs_array[0] & 0x1u, 0u);
2536   // Swap donation status bit.
2537   uint32_t index = schema_.InlinedStringIndex(field);
2538   GOOGLE_DCHECK_GT(index, 0);
2539   if (rhs_donated) {
2540     SetInlinedStringDonated(index, lhs_array);
2541     ClearInlinedStringDonated(index, rhs_array);
2542   } else {  // lhs_donated
2543     ClearInlinedStringDonated(index, lhs_array);
2544     SetInlinedStringDonated(index, rhs_array);
2545   }
2546 }
2547 
2548 // Simple accessors for manipulating has_bits_.
2549 bool Reflection::HasBit(const Message& message,
2550                         const FieldDescriptor* field) const {
2551   GOOGLE_DCHECK(!field->options().weak());
2552   if (schema_.HasBitIndex(field) != static_cast<uint32_t>(-1)) {
2553     return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field));
2554   }
2555 
2556   // Intentionally check here because HasBitIndex(field) != -1 means valid.
2557   CheckInvalidAccess(schema_, field);
2558 
2559   // proto3: no has-bits. All fields present except messages, which are
2560   // present only if their message-field pointer is non-null.
2561   if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2562     return !schema_.IsDefaultInstance(message) &&
2563            GetRaw<const Message*>(message, field) != nullptr;
2564   } else {
2565     // Non-message field (and non-oneof, since that was handled in HasField()
2566     // before calling us), and singular (again, checked in HasField). So, this
2567     // field must be a scalar.
2568 
2569     // Scalar primitive (numeric or string/bytes) fields are present if
2570     // their value is non-zero (numeric) or non-empty (string/bytes). N.B.:
2571     // we must use this definition here, rather than the "scalar fields
2572     // always present" in the proto3 docs, because MergeFrom() semantics
2573     // require presence as "present on wire", and reflection-based merge
2574     // (which uses HasField()) needs to be consistent with this.
2575     switch (field->cpp_type()) {
2576       case FieldDescriptor::CPPTYPE_STRING:
2577         switch (field->options().ctype()) {
2578           default: {
2579             if (IsInlined(field)) {
2580               return !GetField<InlinedStringField>(message, field)
2581                           .GetNoArena()
2582                           .empty();
2583             }
2584 
2585             return GetField<ArenaStringPtr>(message, field).Get().size() > 0;
2586           }
2587         }
2588         return false;
2589       case FieldDescriptor::CPPTYPE_BOOL:
2590         return GetRaw<bool>(message, field) != false;
2591       case FieldDescriptor::CPPTYPE_INT32:
2592         return GetRaw<int32_t>(message, field) != 0;
2593       case FieldDescriptor::CPPTYPE_INT64:
2594         return GetRaw<int64_t>(message, field) != 0;
2595       case FieldDescriptor::CPPTYPE_UINT32:
2596         return GetRaw<uint32_t>(message, field) != 0;
2597       case FieldDescriptor::CPPTYPE_UINT64:
2598         return GetRaw<uint64_t>(message, field) != 0;
2599       case FieldDescriptor::CPPTYPE_FLOAT:
2600         static_assert(sizeof(uint32_t) == sizeof(float),
2601                       "Code assumes uint32_t and float are the same size.");
2602         return GetRaw<uint32_t>(message, field) != 0;
2603       case FieldDescriptor::CPPTYPE_DOUBLE:
2604         static_assert(sizeof(uint64_t) == sizeof(double),
2605                       "Code assumes uint64_t and double are the same size.");
2606         return GetRaw<uint64_t>(message, field) != 0;
2607       case FieldDescriptor::CPPTYPE_ENUM:
2608         return GetRaw<int>(message, field) != 0;
2609       case FieldDescriptor::CPPTYPE_MESSAGE:
2610         // handled above; avoid warning
2611         break;
2612     }
2613     GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit().";
2614     return false;
2615   }
2616 }
2617 
2618 void Reflection::SetBit(Message* message, const FieldDescriptor* field) const {
2619   GOOGLE_DCHECK(!field->options().weak());
2620   const uint32_t index = schema_.HasBitIndex(field);
2621   if (index == static_cast<uint32_t>(-1)) return;
2622   MutableHasBits(message)[index / 32] |=
2623       (static_cast<uint32_t>(1) << (index % 32));
2624 }
2625 
2626 void Reflection::ClearBit(Message* message,
2627                           const FieldDescriptor* field) const {
2628   GOOGLE_DCHECK(!field->options().weak());
2629   const uint32_t index = schema_.HasBitIndex(field);
2630   if (index == static_cast<uint32_t>(-1)) return;
2631   MutableHasBits(message)[index / 32] &=
2632       ~(static_cast<uint32_t>(1) << (index % 32));
2633 }
2634 
2635 void Reflection::SwapBit(Message* message1, Message* message2,
2636                          const FieldDescriptor* field) const {
2637   GOOGLE_DCHECK(!field->options().weak());
2638   if (!schema_.HasHasbits()) {
2639     return;
2640   }
2641   bool temp_has_bit = HasBit(*message1, field);
2642   if (HasBit(*message2, field)) {
2643     SetBit(message1, field);
2644   } else {
2645     ClearBit(message1, field);
2646   }
2647   if (temp_has_bit) {
2648     SetBit(message2, field);
2649   } else {
2650     ClearBit(message2, field);
2651   }
2652 }
2653 
2654 bool Reflection::HasOneof(const Message& message,
2655                           const OneofDescriptor* oneof_descriptor) const {
2656   if (oneof_descriptor->is_synthetic()) {
2657     return HasField(message, oneof_descriptor->field(0));
2658   }
2659   return (GetOneofCase(message, oneof_descriptor) > 0);
2660 }
2661 
2662 void Reflection::SetOneofCase(Message* message,
2663                               const FieldDescriptor* field) const {
2664   *MutableOneofCase(message, field->containing_oneof()) = field->number();
2665 }
2666 
2667 void Reflection::ClearOneofField(Message* message,
2668                                  const FieldDescriptor* field) const {
2669   if (HasOneofField(*message, field)) {
2670     ClearOneof(message, field->containing_oneof());
2671   }
2672 }
2673 
2674 void Reflection::ClearOneof(Message* message,
2675                             const OneofDescriptor* oneof_descriptor) const {
2676   if (oneof_descriptor->is_synthetic()) {
2677     ClearField(message, oneof_descriptor->field(0));
2678     return;
2679   }
2680   // TODO(jieluo): Consider to cache the unused object instead of deleting
2681   // it. It will be much faster if an application switches a lot from
2682   // a few oneof fields.  Time/space tradeoff
2683   uint32_t oneof_case = GetOneofCase(*message, oneof_descriptor);
2684   if (oneof_case > 0) {
2685     const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
2686     if (message->GetArenaForAllocation() == nullptr) {
2687       switch (field->cpp_type()) {
2688         case FieldDescriptor::CPPTYPE_STRING: {
2689           switch (field->options().ctype()) {
2690             default:  // TODO(kenton):  Support other string reps.
2691             case FieldOptions::STRING: {
2692               // Oneof string fields are never set as a default instance.
2693               // We just need to pass some arbitrary default string to make it
2694               // work. This allows us to not have the real default accessible
2695               // from reflection.
2696               MutableField<ArenaStringPtr>(message, field)->Destroy();
2697               break;
2698             }
2699           }
2700           break;
2701         }
2702 
2703         case FieldDescriptor::CPPTYPE_MESSAGE:
2704           delete *MutableRaw<Message*>(message, field);
2705           break;
2706         default:
2707           break;
2708       }
2709     } else {
2710     }
2711 
2712     *MutableOneofCase(message, oneof_descriptor) = 0;
2713   }
2714 }
2715 
2716 #define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE)                                  \
2717   template <>                                                              \
2718   const RepeatedField<TYPE>& Reflection::GetRepeatedFieldInternal<TYPE>(   \
2719       const Message& message, const FieldDescriptor* field) const {        \
2720     return *static_cast<RepeatedField<TYPE>*>(MutableRawRepeatedField(     \
2721         const_cast<Message*>(&message), field, CPPTYPE, CTYPE, nullptr));  \
2722   }                                                                        \
2723                                                                            \
2724   template <>                                                              \
2725   RepeatedField<TYPE>* Reflection::MutableRepeatedFieldInternal<TYPE>(     \
2726       Message * message, const FieldDescriptor* field) const {             \
2727     return static_cast<RepeatedField<TYPE>*>(                              \
2728         MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, nullptr)); \
2729   }
2730 
2731 HANDLE_TYPE(int32_t, FieldDescriptor::CPPTYPE_INT32, -1);
2732 HANDLE_TYPE(int64_t, FieldDescriptor::CPPTYPE_INT64, -1);
2733 HANDLE_TYPE(uint32_t, FieldDescriptor::CPPTYPE_UINT32, -1);
2734 HANDLE_TYPE(uint64_t, FieldDescriptor::CPPTYPE_UINT64, -1);
2735 HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1);
2736 HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1);
2737 HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1);
2738 
2739 
2740 #undef HANDLE_TYPE
2741 
2742 void* Reflection::MutableRawRepeatedString(Message* message,
2743                                            const FieldDescriptor* field,
2744                                            bool is_string) const {
2745   (void)is_string;  // Parameter is used by Google-internal code.
2746   return MutableRawRepeatedField(message, field,
2747                                  FieldDescriptor::CPPTYPE_STRING,
2748                                  FieldOptions::STRING, nullptr);
2749 }
2750 
2751 // Template implementations of basic accessors.  Inline because each
2752 // template instance is only called from one location.  These are
2753 // used for all types except messages.
2754 template <typename Type>
2755 const Type& Reflection::GetField(const Message& message,
2756                                  const FieldDescriptor* field) const {
2757   return GetRaw<Type>(message, field);
2758 }
2759 
2760 template <typename Type>
2761 void Reflection::SetField(Message* message, const FieldDescriptor* field,
2762                           const Type& value) const {
2763   bool real_oneof = schema_.InRealOneof(field);
2764   if (real_oneof && !HasOneofField(*message, field)) {
2765     ClearOneof(message, field->containing_oneof());
2766   }
2767   *MutableRaw<Type>(message, field) = value;
2768   real_oneof ? SetOneofCase(message, field) : SetBit(message, field);
2769 }
2770 
2771 template <typename Type>
2772 Type* Reflection::MutableField(Message* message,
2773                                const FieldDescriptor* field) const {
2774   schema_.InRealOneof(field) ? SetOneofCase(message, field)
2775                              : SetBit(message, field);
2776   return MutableRaw<Type>(message, field);
2777 }
2778 
2779 template <typename Type>
2780 const Type& Reflection::GetRepeatedField(const Message& message,
2781                                          const FieldDescriptor* field,
2782                                          int index) const {
2783   return GetRaw<RepeatedField<Type> >(message, field).Get(index);
2784 }
2785 
2786 template <typename Type>
2787 const Type& Reflection::GetRepeatedPtrField(const Message& message,
2788                                             const FieldDescriptor* field,
2789                                             int index) const {
2790   return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
2791 }
2792 
2793 template <typename Type>
2794 void Reflection::SetRepeatedField(Message* message,
2795                                   const FieldDescriptor* field, int index,
2796                                   Type value) const {
2797   MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
2798 }
2799 
2800 template <typename Type>
2801 Type* Reflection::MutableRepeatedField(Message* message,
2802                                        const FieldDescriptor* field,
2803                                        int index) const {
2804   RepeatedPtrField<Type>* repeated =
2805       MutableRaw<RepeatedPtrField<Type> >(message, field);
2806   return repeated->Mutable(index);
2807 }
2808 
2809 template <typename Type>
2810 void Reflection::AddField(Message* message, const FieldDescriptor* field,
2811                           const Type& value) const {
2812   MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
2813 }
2814 
2815 template <typename Type>
2816 Type* Reflection::AddField(Message* message,
2817                            const FieldDescriptor* field) const {
2818   RepeatedPtrField<Type>* repeated =
2819       MutableRaw<RepeatedPtrField<Type> >(message, field);
2820   return repeated->Add();
2821 }
2822 
2823 MessageFactory* Reflection::GetMessageFactory() const {
2824   return message_factory_;
2825 }
2826 
2827 void* Reflection::RepeatedFieldData(Message* message,
2828                                     const FieldDescriptor* field,
2829                                     FieldDescriptor::CppType cpp_type,
2830                                     const Descriptor* message_type) const {
2831   GOOGLE_CHECK(field->is_repeated());
2832   GOOGLE_CHECK(field->cpp_type() == cpp_type ||
2833         (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
2834          cpp_type == FieldDescriptor::CPPTYPE_INT32))
2835       << "The type parameter T in RepeatedFieldRef<T> API doesn't match "
2836       << "the actual field type (for enums T should be the generated enum "
2837       << "type or int32_t).";
2838   if (message_type != nullptr) {
2839     GOOGLE_CHECK_EQ(message_type, field->message_type());
2840   }
2841   if (field->is_extension()) {
2842     return MutableExtensionSet(message)->MutableRawRepeatedField(
2843         field->number(), field->type(), field->is_packed(), field);
2844   } else {
2845     return MutableRawNonOneof<char>(message, field);
2846   }
2847 }
2848 
2849 MapFieldBase* Reflection::MutableMapData(Message* message,
2850                                          const FieldDescriptor* field) const {
2851   USAGE_CHECK(IsMapFieldInApi(field), "GetMapData",
2852               "Field is not a map field.");
2853   return MutableRaw<MapFieldBase>(message, field);
2854 }
2855 
2856 const MapFieldBase* Reflection::GetMapData(const Message& message,
2857                                            const FieldDescriptor* field) const {
2858   USAGE_CHECK(IsMapFieldInApi(field), "GetMapData",
2859               "Field is not a map field.");
2860   return &(GetRaw<MapFieldBase>(message, field));
2861 }
2862 
2863 namespace {
2864 
2865 // Helper function to transform migration schema into reflection schema.
2866 ReflectionSchema MigrationToReflectionSchema(
2867     const Message* const* default_instance, const uint32_t* offsets,
2868     MigrationSchema migration_schema) {
2869   ReflectionSchema result;
2870   result.default_instance_ = *default_instance;
2871   // First 7 offsets are offsets to the special fields. The following offsets
2872   // are the proto fields.
2873   result.offsets_ = offsets + migration_schema.offsets_index + 6;
2874   result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index;
2875   result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0];
2876   result.metadata_offset_ = offsets[migration_schema.offsets_index + 1];
2877   result.extensions_offset_ = offsets[migration_schema.offsets_index + 2];
2878   result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3];
2879   result.object_size_ = migration_schema.object_size;
2880   result.weak_field_map_offset_ = offsets[migration_schema.offsets_index + 4];
2881   result.inlined_string_donated_offset_ =
2882       offsets[migration_schema.offsets_index + 5];
2883   result.inlined_string_indices_ =
2884       offsets + migration_schema.inlined_string_indices_index;
2885   return result;
2886 }
2887 
2888 }  // namespace
2889 
2890 class AssignDescriptorsHelper {
2891  public:
2892   AssignDescriptorsHelper(MessageFactory* factory,
2893                           Metadata* file_level_metadata,
2894                           const EnumDescriptor** file_level_enum_descriptors,
2895                           const MigrationSchema* schemas,
2896                           const Message* const* default_instance_data,
2897                           const uint32_t* offsets)
2898       : factory_(factory),
2899         file_level_metadata_(file_level_metadata),
2900         file_level_enum_descriptors_(file_level_enum_descriptors),
2901         schemas_(schemas),
2902         default_instance_data_(default_instance_data),
2903         offsets_(offsets) {}
2904 
2905   void AssignMessageDescriptor(const Descriptor* descriptor) {
2906     for (int i = 0; i < descriptor->nested_type_count(); i++) {
2907       AssignMessageDescriptor(descriptor->nested_type(i));
2908     }
2909 
2910     file_level_metadata_->descriptor = descriptor;
2911 
2912     file_level_metadata_->reflection =
2913         new Reflection(descriptor,
2914                        MigrationToReflectionSchema(default_instance_data_,
2915                                                    offsets_, *schemas_),
2916                        DescriptorPool::internal_generated_pool(), factory_);
2917     for (int i = 0; i < descriptor->enum_type_count(); i++) {
2918       AssignEnumDescriptor(descriptor->enum_type(i));
2919     }
2920     schemas_++;
2921     default_instance_data_++;
2922     file_level_metadata_++;
2923   }
2924 
2925   void AssignEnumDescriptor(const EnumDescriptor* descriptor) {
2926     *file_level_enum_descriptors_ = descriptor;
2927     file_level_enum_descriptors_++;
2928   }
2929 
2930   const Metadata* GetCurrentMetadataPtr() const { return file_level_metadata_; }
2931 
2932  private:
2933   MessageFactory* factory_;
2934   Metadata* file_level_metadata_;
2935   const EnumDescriptor** file_level_enum_descriptors_;
2936   const MigrationSchema* schemas_;
2937   const Message* const* default_instance_data_;
2938   const uint32_t* offsets_;
2939 };
2940 
2941 namespace {
2942 
2943 // We have the routines that assign descriptors and build reflection
2944 // automatically delete the allocated reflection. MetadataOwner owns
2945 // all the allocated reflection instances.
2946 struct MetadataOwner {
2947   ~MetadataOwner() {
2948     for (auto range : metadata_arrays_) {
2949       for (const Metadata* m = range.first; m < range.second; m++) {
2950         delete m->reflection;
2951       }
2952     }
2953   }
2954 
2955   void AddArray(const Metadata* begin, const Metadata* end) {
2956     mu_.Lock();
2957     metadata_arrays_.push_back(std::make_pair(begin, end));
2958     mu_.Unlock();
2959   }
2960 
2961   static MetadataOwner* Instance() {
2962     static MetadataOwner* res = OnShutdownDelete(new MetadataOwner);
2963     return res;
2964   }
2965 
2966  private:
2967   MetadataOwner() = default;  // private because singleton
2968 
2969   WrappedMutex mu_;
2970   std::vector<std::pair<const Metadata*, const Metadata*> > metadata_arrays_;
2971 };
2972 
2973 void AddDescriptors(const DescriptorTable* table);
2974 
2975 void AssignDescriptorsImpl(const DescriptorTable* table, bool eager) {
2976   // Ensure the file descriptor is added to the pool.
2977   {
2978     // This only happens once per proto file. So a global mutex to serialize
2979     // calls to AddDescriptors.
2980     static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED};
2981     mu.Lock();
2982     AddDescriptors(table);
2983     mu.Unlock();
2984   }
2985   if (eager) {
2986     // Normally we do not want to eagerly build descriptors of our deps.
2987     // However if this proto is optimized for code size (ie using reflection)
2988     // and it has a message extending a custom option of a descriptor with that
2989     // message being optimized for code size as well. Building the descriptors
2990     // in this file requires parsing the serialized file descriptor, which now
2991     // requires parsing the message extension, which potentially requires
2992     // building the descriptor of the message extending one of the options.
2993     // However we are already updating descriptor pool under a lock. To prevent
2994     // this the compiler statically looks for this case and we just make sure we
2995     // first build the descriptors of all our dependencies, preventing the
2996     // deadlock.
2997     int num_deps = table->num_deps;
2998     for (int i = 0; i < num_deps; i++) {
2999       // In case of weak fields deps[i] could be null.
3000       if (table->deps[i]) AssignDescriptors(table->deps[i], true);
3001     }
3002   }
3003 
3004   // Fill the arrays with pointers to descriptors and reflection classes.
3005   const FileDescriptor* file =
3006       DescriptorPool::internal_generated_pool()->FindFileByName(
3007           table->filename);
3008   GOOGLE_CHECK(file != nullptr);
3009 
3010   MessageFactory* factory = MessageFactory::generated_factory();
3011 
3012   AssignDescriptorsHelper helper(
3013       factory, table->file_level_metadata, table->file_level_enum_descriptors,
3014       table->schemas, table->default_instances, table->offsets);
3015 
3016   for (int i = 0; i < file->message_type_count(); i++) {
3017     helper.AssignMessageDescriptor(file->message_type(i));
3018   }
3019 
3020   for (int i = 0; i < file->enum_type_count(); i++) {
3021     helper.AssignEnumDescriptor(file->enum_type(i));
3022   }
3023   if (file->options().cc_generic_services()) {
3024     for (int i = 0; i < file->service_count(); i++) {
3025       table->file_level_service_descriptors[i] = file->service(i);
3026     }
3027   }
3028   MetadataOwner::Instance()->AddArray(table->file_level_metadata,
3029                                       helper.GetCurrentMetadataPtr());
3030 }
3031 
3032 void AddDescriptorsImpl(const DescriptorTable* table) {
3033   // Reflection refers to the default fields so make sure they are initialized.
3034   internal::InitProtobufDefaults();
3035 
3036   // Ensure all dependent descriptors are registered to the generated descriptor
3037   // pool and message factory.
3038   int num_deps = table->num_deps;
3039   for (int i = 0; i < num_deps; i++) {
3040     // In case of weak fields deps[i] could be null.
3041     if (table->deps[i]) AddDescriptors(table->deps[i]);
3042   }
3043 
3044   // Register the descriptor of this file.
3045   DescriptorPool::InternalAddGeneratedFile(table->descriptor, table->size);
3046   MessageFactory::InternalRegisterGeneratedFile(table);
3047 }
3048 
3049 void AddDescriptors(const DescriptorTable* table) {
3050   // AddDescriptors is not thread safe. Callers need to ensure calls are
3051   // properly serialized. This function is only called pre-main by global
3052   // descriptors and we can assume single threaded access or it's called
3053   // by AssignDescriptorImpl which uses a mutex to sequence calls.
3054   if (table->is_initialized) return;
3055   table->is_initialized = true;
3056   AddDescriptorsImpl(table);
3057 }
3058 
3059 }  // namespace
3060 
3061 // Separate function because it needs to be a friend of
3062 // Reflection
3063 void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) {
3064   for (int i = 0; i < size; i++) {
3065     const Reflection* reflection = file_level_metadata[i].reflection;
3066     MessageFactory::InternalRegisterGeneratedMessage(
3067         file_level_metadata[i].descriptor,
3068         reflection->schema_.default_instance_);
3069   }
3070 }
3071 
3072 namespace internal {
3073 
3074 Metadata AssignDescriptors(const DescriptorTable* (*table)(),
3075                            internal::once_flag* once,
3076                            const Metadata& metadata) {
3077   call_once(*once, [=] {
3078     auto* t = table();
3079     AssignDescriptorsImpl(t, t->is_eager);
3080   });
3081 
3082   return metadata;
3083 }
3084 
3085 void AssignDescriptors(const DescriptorTable* table, bool eager) {
3086   if (!eager) eager = table->is_eager;
3087   call_once(*table->once, AssignDescriptorsImpl, table, eager);
3088 }
3089 
3090 AddDescriptorsRunner::AddDescriptorsRunner(const DescriptorTable* table) {
3091   AddDescriptors(table);
3092 }
3093 
3094 void RegisterFileLevelMetadata(const DescriptorTable* table) {
3095   AssignDescriptors(table);
3096   RegisterAllTypesInternal(table->file_level_metadata, table->num_messages);
3097 }
3098 
3099 void UnknownFieldSetSerializer(const uint8_t* base, uint32_t offset,
3100                                uint32_t /*tag*/, uint32_t /*has_offset*/,
3101                                io::CodedOutputStream* output) {
3102   const void* ptr = base + offset;
3103   const InternalMetadata* metadata = static_cast<const InternalMetadata*>(ptr);
3104   if (metadata->have_unknown_fields()) {
3105     metadata->unknown_fields<UnknownFieldSet>(UnknownFieldSet::default_instance)
3106         .SerializeToCodedStream(output);
3107   }
3108 }
3109 
3110 }  // namespace internal
3111 }  // namespace protobuf
3112 }  // namespace google
3113 
3114 #include <google/protobuf/port_undef.inc>
3115