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