• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 // Author: kenton@google.com (Kenton Varda)
9 //  Based on original Protocol Buffers design by
10 //  Sanjay Ghemawat, Jeff Dean, and others.
11 
12 #include "google/protobuf/generated_message_reflection.h"
13 
14 #include <algorithm>
15 #include <atomic>
16 #include <cstdint>
17 #include <cstring>
18 #include <new>  // IWYU pragma: keep for operator delete
19 #include <queue>
20 #include <string>
21 #include <type_traits>
22 #include <utility>
23 #include <vector>
24 
25 #include "absl/base/attributes.h"
26 #include "absl/base/call_once.h"
27 #include "absl/base/const_init.h"
28 #include "absl/container/flat_hash_set.h"
29 #include "absl/log/absl_check.h"
30 #include "absl/log/absl_log.h"
31 #include "absl/strings/str_format.h"
32 #include "absl/strings/string_view.h"
33 #include "absl/synchronization/mutex.h"
34 #include "google/protobuf/descriptor.h"
35 #include "google/protobuf/descriptor.pb.h"
36 #include "google/protobuf/extension_set.h"
37 #include "google/protobuf/generated_message_tctable_decl.h"
38 #include "google/protobuf/generated_message_tctable_gen.h"
39 #include "google/protobuf/generated_message_tctable_impl.h"
40 #include "google/protobuf/generated_message_util.h"
41 #include "google/protobuf/inlined_string_field.h"
42 #include "google/protobuf/map_field.h"
43 #include "google/protobuf/message.h"
44 #include "google/protobuf/message_lite.h"
45 #include "google/protobuf/port.h"
46 #include "google/protobuf/raw_ptr.h"
47 #include "google/protobuf/reflection_visit_fields.h"
48 #include "google/protobuf/repeated_field.h"
49 #include "google/protobuf/repeated_ptr_field.h"
50 #include "google/protobuf/unknown_field_set.h"
51 
52 
53 // clang-format off
54 #include "google/protobuf/port_def.inc"
55 // clang-format on
56 
57 #define GOOGLE_PROTOBUF_HAS_ONEOF
58 
59 using google::protobuf::internal::ArenaStringPtr;
60 using google::protobuf::internal::DescriptorTable;
61 using google::protobuf::internal::ExtensionSet;
62 using google::protobuf::internal::GenericTypeHandler;
63 using google::protobuf::internal::GetEmptyString;
64 using google::protobuf::internal::InlinedStringField;
65 using google::protobuf::internal::InternalMetadata;
66 using google::protobuf::internal::LazyField;
67 using google::protobuf::internal::MapFieldBase;
68 using google::protobuf::internal::MigrationSchema;
69 using google::protobuf::internal::OnShutdownDelete;
70 using google::protobuf::internal::ReflectionSchema;
71 using google::protobuf::internal::RepeatedPtrFieldBase;
72 using google::protobuf::internal::StringSpaceUsedExcludingSelfLong;
73 using google::protobuf::internal::cpp::IsLazilyInitializedFile;
74 
75 namespace google {
76 namespace protobuf {
77 
78 namespace {
IsMapFieldInApi(const FieldDescriptor * field)79 bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); }
80 
MaybeForceCopy(Arena * arena,Message * msg)81 Message* MaybeForceCopy(Arena* arena, Message* msg) {
82   if (arena != nullptr || msg == nullptr) return msg;
83 
84   Message* copy = msg->New();
85   copy->MergeFrom(*msg);
86   delete msg;
87   return copy;
88 }
89 }  // anonymous namespace
90 
91 namespace internal {
92 
InitializeFileDescriptorDefaultInstances()93 void InitializeFileDescriptorDefaultInstances() {
94 #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES)
95   static std::true_type init =
96       (InitializeFileDescriptorDefaultInstancesSlow(), std::true_type{});
97   (void)init;
98 #endif  // !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES)
99 }
100 
InitializeLazyExtensionSet()101 void InitializeLazyExtensionSet() {
102 }
103 
ParseNamedEnum(const EnumDescriptor * descriptor,absl::string_view name,int * value)104 bool ParseNamedEnum(const EnumDescriptor* descriptor, absl::string_view name,
105                     int* value) {
106   const EnumValueDescriptor* d = descriptor->FindValueByName(name);
107   if (d == nullptr) return false;
108   *value = d->number();
109   return true;
110 }
111 
NameOfEnum(const EnumDescriptor * descriptor,int value)112 const std::string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
113   const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
114   return (d == nullptr ? GetEmptyString() : internal::NameOfEnumAsString(d));
115 }
116 
117 // Internal helper routine for NameOfDenseEnum in the header file.
118 // Allocates and fills a simple array of string pointers, based on
119 // reflection information about the names of the enums.  This routine
120 // allocates max_val + 1 entries, under the assumption that all the enums
121 // fall in the range [min_val .. max_val].
MakeDenseEnumCache(const EnumDescriptor * desc,int min_val,int max_val)122 const std::string** MakeDenseEnumCache(const EnumDescriptor* desc, int min_val,
123                                        int max_val) {
124   auto* str_ptrs =
125       new const std::string*[static_cast<size_t>(max_val - min_val + 1)]();
126   const int count = desc->value_count();
127   for (int i = 0; i < count; ++i) {
128     const int num = desc->value(i)->number();
129     if (str_ptrs[num - min_val] == nullptr) {
130       // Don't over-write an existing entry, because in case of duplication, the
131       // first one wins.
132       str_ptrs[num - min_val] = &internal::NameOfEnumAsString(desc->value(i));
133     }
134   }
135   // Change any unfilled entries to point to the empty string.
136   for (int i = 0; i < max_val - min_val + 1; ++i) {
137     if (str_ptrs[i] == nullptr) str_ptrs[i] = &GetEmptyStringAlreadyInited();
138   }
139   return str_ptrs;
140 }
141 
NameOfDenseEnumSlow(int v,DenseEnumCacheInfo * deci)142 PROTOBUF_NOINLINE const std::string& NameOfDenseEnumSlow(
143     int v, DenseEnumCacheInfo* deci) {
144   if (v < deci->min_val || v > deci->max_val)
145     return GetEmptyStringAlreadyInited();
146 
147   const std::string** new_cache =
148       MakeDenseEnumCache(deci->descriptor_fn(), deci->min_val, deci->max_val);
149   const std::string** old_cache = nullptr;
150 
151   if (deci->cache.compare_exchange_strong(old_cache, new_cache,
152                                           std::memory_order_release,
153                                           std::memory_order_acquire)) {
154     // We successfully stored our new cache, and the old value was nullptr.
155     return *new_cache[v - deci->min_val];
156   } else {
157     // In the time it took to create our enum cache, another thread also
158     //  created one, and put it into deci->cache.  So delete ours, and
159     // use theirs instead.
160     delete[] new_cache;
161     return *old_cache[v - deci->min_val];
162   }
163 }
164 
165 }  // namespace internal
166 
167 // ===================================================================
168 // Helpers for reporting usage errors (e.g. trying to use GetInt32() on
169 // a string field).
170 
171 namespace {
172 
173 using internal::GetConstPointerAtOffset;
174 using internal::GetConstRefAtOffset;
175 using internal::GetPointerAtOffset;
176 
ReportReflectionUsageError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,const char * description)177 void ReportReflectionUsageError(const Descriptor* descriptor,
178                                 const FieldDescriptor* field,
179                                 const char* method, const char* description) {
180   ABSL_LOG(FATAL) << "Protocol Buffer reflection usage error:\n"
181                      "  Method      : google::protobuf::Reflection::"
182                   << method
183                   << "\n"
184                      "  Message type: "
185                   << descriptor->full_name()
186                   << "\n"
187                      "  Field       : "
188                   << field->full_name()
189                   << "\n"
190                      "  Problem     : "
191                   << description;
192 }
193 
194 #ifndef NDEBUG
ReportReflectionUsageMessageError(const Descriptor * expected,const Descriptor * actual,const FieldDescriptor * field,const char * method)195 void ReportReflectionUsageMessageError(const Descriptor* expected,
196                                        const Descriptor* actual,
197                                        const FieldDescriptor* field,
198                                        const char* method) {
199   ABSL_LOG(FATAL) << absl::StrFormat(
200       "Protocol Buffer reflection usage error:\n"
201       "  Method       : google::protobuf::Reflection::%s\n"
202       "  Expected type: %s\n"
203       "  Actual type  : %s\n"
204       "  Field        : %s\n"
205       "  Problem      : Message is not the right object for reflection",
206       method, expected->full_name(), actual->full_name(), field->full_name());
207 }
208 #endif
209 
210 const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = {
211     "INVALID_CPPTYPE", "CPPTYPE_INT32",  "CPPTYPE_INT64",  "CPPTYPE_UINT32",
212     "CPPTYPE_UINT64",  "CPPTYPE_DOUBLE", "CPPTYPE_FLOAT",  "CPPTYPE_BOOL",
213     "CPPTYPE_ENUM",    "CPPTYPE_STRING", "CPPTYPE_MESSAGE"};
214 
ReportReflectionUsageTypeError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,FieldDescriptor::CppType expected_type)215 static void ReportReflectionUsageTypeError(
216     const Descriptor* descriptor, const FieldDescriptor* field,
217     const char* method, FieldDescriptor::CppType expected_type) {
218   ABSL_LOG(FATAL)
219       << "Protocol Buffer reflection usage error:\n"
220          "  Method      : google::protobuf::Reflection::"
221       << method
222       << "\n"
223          "  Message type: "
224       << descriptor->full_name()
225       << "\n"
226          "  Field       : "
227       << field->full_name()
228       << "\n"
229          "  Problem     : Field is not the right type for this message:\n"
230          "    Expected  : "
231       << cpptype_names_[expected_type]
232       << "\n"
233          "    Field type: "
234       << cpptype_names_[field->cpp_type()];
235 }
236 
ReportReflectionUsageEnumTypeError(const Descriptor * descriptor,const FieldDescriptor * field,const char * method,const EnumValueDescriptor * value)237 static void ReportReflectionUsageEnumTypeError(
238     const Descriptor* descriptor, const FieldDescriptor* field,
239     const char* method, const EnumValueDescriptor* value) {
240   ABSL_LOG(FATAL) << "Protocol Buffer reflection usage error:\n"
241                      "  Method      : google::protobuf::Reflection::"
242                   << method
243                   << "\n"
244                      "  Message type: "
245                   << descriptor->full_name()
246                   << "\n"
247                      "  Field       : "
248                   << field->full_name()
249                   << "\n"
250                      "  Problem     : Enum value did not match field type:\n"
251                      "    Expected  : "
252                   << field->enum_type()->full_name()
253                   << "\n"
254                      "    Actual    : "
255                   << value->full_name();
256 }
257 
258 #define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \
259   if (!(CONDITION))                                       \
260   ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION)
261 #define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \
262   USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION)
263 #define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \
264   USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION)
265 
266 #define USAGE_CHECK_TYPE(METHOD, CPPTYPE)                      \
267   if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \
268   ReportReflectionUsageTypeError(descriptor_, field, #METHOD,  \
269                                  FieldDescriptor::CPPTYPE_##CPPTYPE)
270 
271 #define USAGE_CHECK_ENUM_VALUE(METHOD)     \
272   if (value->type() != field->enum_type()) \
273   ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value)
274 
275 #ifdef NDEBUG
276 // Avoid a virtual method call in optimized builds.
277 #define USAGE_CHECK_MESSAGE(METHOD, MESSAGE)
278 #else
279 #define USAGE_CHECK_MESSAGE(METHOD, MESSAGE)                                 \
280   if (this != (MESSAGE)->GetReflection())                                    \
281   ReportReflectionUsageMessageError(descriptor_, (MESSAGE)->GetDescriptor(), \
282                                     field, #METHOD)
283 #endif
284 
285 #define USAGE_CHECK_MESSAGE_TYPE(METHOD)                        \
286   USAGE_CHECK_EQ(field->containing_type(), descriptor_, METHOD, \
287                  "Field does not match message type.");
288 #define USAGE_CHECK_SINGULAR(METHOD)                                      \
289   USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
290                  "Field is repeated; the method requires a singular field.")
291 #define USAGE_CHECK_REPEATED(METHOD)                                      \
292   USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
293                  "Field is singular; the method requires a repeated field.")
294 
295 #define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \
296   USAGE_CHECK_MESSAGE(METHOD, &message);        \
297   USAGE_CHECK_MESSAGE_TYPE(METHOD);             \
298   USAGE_CHECK_##LABEL(METHOD);                  \
299   USAGE_CHECK_TYPE(METHOD, CPPTYPE)
300 
301 #define USAGE_MUTABLE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \
302   USAGE_CHECK_MESSAGE(METHOD, message);                 \
303   USAGE_CHECK_MESSAGE_TYPE(METHOD);                     \
304   USAGE_CHECK_##LABEL(METHOD);                          \
305   USAGE_CHECK_TYPE(METHOD, CPPTYPE)
306 
307 }  // namespace
308 
309 // ===================================================================
310 
Reflection(const Descriptor * descriptor,const internal::ReflectionSchema & schema,const DescriptorPool * pool,MessageFactory * factory)311 Reflection::Reflection(const Descriptor* descriptor,
312                        const internal::ReflectionSchema& schema,
313                        const DescriptorPool* pool, MessageFactory* factory)
314     : descriptor_(descriptor),
315       schema_(schema),
316       descriptor_pool_(
317           (pool == nullptr) ? DescriptorPool::internal_generated_pool() : pool),
318       message_factory_(factory),
319       last_non_weak_field_index_(-1) {
320   last_non_weak_field_index_ = descriptor_->field_count() - 1;
321 }
322 
~Reflection()323 Reflection::~Reflection() {
324   // No need to use sized delete. This code path is uncommon and it would not be
325   // worth saving or recalculating the size.
326   ::operator delete(const_cast<internal::TcParseTableBase*>(tcparse_table_));
327 }
328 
GetUnknownFields(const Message & message) const329 const UnknownFieldSet& Reflection::GetUnknownFields(
330     const Message& message) const {
331   return GetInternalMetadata(message).unknown_fields<UnknownFieldSet>(
332       UnknownFieldSet::default_instance);
333 }
334 
MutableUnknownFields(Message * message) const335 UnknownFieldSet* Reflection::MutableUnknownFields(Message* message) const {
336   return MutableInternalMetadata(message)
337       ->mutable_unknown_fields<UnknownFieldSet>();
338 }
339 
IsLazyExtension(const Message & message,const FieldDescriptor * field) const340 bool Reflection::IsLazyExtension(const Message& message,
341                                  const FieldDescriptor* field) const {
342   return field->is_extension() &&
343          GetExtensionSet(message).HasLazy(field->number());
344 }
345 
IsLazilyVerifiedLazyField(const FieldDescriptor * field) const346 bool Reflection::IsLazilyVerifiedLazyField(const FieldDescriptor* field) const {
347   if (field->type() != FieldDescriptor::TYPE_MESSAGE || field->is_repeated()) {
348     return false;
349   }
350   return field->options().unverified_lazy();
351 }
352 
IsEagerlyVerifiedLazyField(const FieldDescriptor * field) const353 bool Reflection::IsEagerlyVerifiedLazyField(
354     const FieldDescriptor* field) const {
355   if (field->type() != FieldDescriptor::TYPE_MESSAGE) return false;
356 
357   // Message fields with [lazy=true] will be eagerly verified
358   // (go/verified-lazy).
359   if (field->options().lazy() && !field->is_repeated()) return true;
360   return schema_.IsEagerlyVerifiedLazyField(field);
361 }
362 
GetLazyStyle(const FieldDescriptor * field) const363 internal::field_layout::TransformValidation Reflection::GetLazyStyle(
364     const FieldDescriptor* field) const {
365   if (IsEagerlyVerifiedLazyField(field)) {
366     return internal::field_layout::kTvEager;
367   }
368   if (IsLazilyVerifiedLazyField(field)) {
369     return internal::field_layout::kTvLazy;
370   }
371   return {};
372 }
373 
SpaceUsedLong(const Message & message) const374 size_t Reflection::SpaceUsedLong(const Message& message) const {
375   // object_size_ already includes the in-memory representation of each field
376   // in the message, so we only need to account for additional memory used by
377   // the fields.
378   size_t total_size = schema_.GetObjectSize();
379 
380   total_size += GetUnknownFields(message).SpaceUsedExcludingSelfLong();
381 
382   if (schema_.HasExtensionSet()) {
383     total_size += GetExtensionSet(message).SpaceUsedExcludingSelfLong();
384   }
385   for (int i = 0; i <= last_non_weak_field_index_; i++) {
386     const FieldDescriptor* field = descriptor_->field(i);
387     if (field->is_repeated()) {
388       switch (field->cpp_type()) {
389 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                           \
390   case FieldDescriptor::CPPTYPE_##UPPERCASE:                        \
391     total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \
392                       .SpaceUsedExcludingSelfLong();                \
393     break
394 
395         HANDLE_TYPE(INT32, int32_t);
396         HANDLE_TYPE(INT64, int64_t);
397         HANDLE_TYPE(UINT32, uint32_t);
398         HANDLE_TYPE(UINT64, uint64_t);
399         HANDLE_TYPE(DOUBLE, double);
400         HANDLE_TYPE(FLOAT, float);
401         HANDLE_TYPE(BOOL, bool);
402         HANDLE_TYPE(ENUM, int);
403 #undef HANDLE_TYPE
404 
405         case FieldDescriptor::CPPTYPE_STRING:
406           switch (field->cpp_string_type()) {
407             case FieldDescriptor::CppStringType::kCord:
408               total_size += GetRaw<RepeatedField<absl::Cord>>(message, field)
409                                 .SpaceUsedExcludingSelfLong();
410               break;
411             case FieldDescriptor::CppStringType::kView:
412             case FieldDescriptor::CppStringType::kString:
413               total_size +=
414                   GetRaw<RepeatedPtrField<std::string> >(message, field)
415                       .SpaceUsedExcludingSelfLong();
416               break;
417           }
418           break;
419 
420         case FieldDescriptor::CPPTYPE_MESSAGE:
421           if (IsMapFieldInApi(field)) {
422             total_size += GetRaw<internal::MapFieldBase>(message, field)
423                               .SpaceUsedExcludingSelfLong();
424           } else {
425             // We don't know which subclass of RepeatedPtrFieldBase the type is,
426             // so we use RepeatedPtrFieldBase directly.
427             total_size +=
428                 GetRaw<RepeatedPtrFieldBase>(message, field)
429                     .SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >();
430           }
431 
432           break;
433       }
434     } else {
435       if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
436         continue;
437       }
438       switch (field->cpp_type()) {
439         case FieldDescriptor::CPPTYPE_INT32:
440         case FieldDescriptor::CPPTYPE_INT64:
441         case FieldDescriptor::CPPTYPE_UINT32:
442         case FieldDescriptor::CPPTYPE_UINT64:
443         case FieldDescriptor::CPPTYPE_DOUBLE:
444         case FieldDescriptor::CPPTYPE_FLOAT:
445         case FieldDescriptor::CPPTYPE_BOOL:
446         case FieldDescriptor::CPPTYPE_ENUM:
447           // Field is inline, so we've already counted it.
448           break;
449 
450         case FieldDescriptor::CPPTYPE_STRING: {
451           switch (field->cpp_string_type()) {
452             case FieldDescriptor::CppStringType::kCord:
453               if (schema_.InRealOneof(field)) {
454                 total_size += GetField<absl::Cord*>(message, field)
455                                   ->EstimatedMemoryUsage();
456 
457               } else {
458                 // sizeof(absl::Cord) is included to self.
459                 total_size += GetField<absl::Cord>(message, field)
460                                   .EstimatedMemoryUsage() -
461                               sizeof(absl::Cord);
462               }
463               break;
464             case FieldDescriptor::CppStringType::kView:
465             case FieldDescriptor::CppStringType::kString:
466               if (IsInlined(field)) {
467                 const std::string* ptr =
468                     &GetField<InlinedStringField>(message, field).GetNoArena();
469                 total_size += StringSpaceUsedExcludingSelfLong(*ptr);
470               } else {
471                 // Initially, the string points to the default value stored
472                 // in the prototype. Only count the string if it has been
473                 // changed from the default value.
474                 // Except oneof fields, those never point to a default instance,
475                 // and there is no default instance to point to.
476                 const auto& str = GetField<ArenaStringPtr>(message, field);
477                 if (!str.IsDefault() || schema_.InRealOneof(field)) {
478                   // string fields are represented by just a pointer, so also
479                   // include sizeof(string) as well.
480                   total_size += sizeof(std::string) +
481                                 StringSpaceUsedExcludingSelfLong(str.Get());
482                 }
483               }
484               break;
485           }
486           break;
487         }
488 
489         case FieldDescriptor::CPPTYPE_MESSAGE:
490           if (schema_.IsDefaultInstance(message)) {
491             // For singular fields, the prototype just stores a pointer to the
492             // external type's prototype, so there is no extra memory usage.
493           } else {
494             const Message* sub_message = GetRaw<const Message*>(message, field);
495             if (sub_message != nullptr) {
496               total_size += sub_message->SpaceUsedLong();
497             }
498           }
499           break;
500       }
501     }
502   }
503   if (internal::DebugHardenFuzzMessageSpaceUsedLong()) {
504     // Use both `this` and `dummy` to generate the seed so that the scale factor
505     // is both per-object and non-predictable, but consistent across multiple
506     // calls in the same binary.
507     static bool dummy;
508     uintptr_t seed =
509         reinterpret_cast<uintptr_t>(&dummy) ^ reinterpret_cast<uintptr_t>(this);
510     // Fuzz the size by +/- 50%.
511     double scale = (static_cast<double>(seed % 10000) / 10000) + 0.5;
512     return total_size * scale;
513   } else {
514     return total_size;
515   }
516 }
517 
518 namespace {
519 
520 template <bool unsafe_shallow_swap>
521 struct OneofFieldMover {
522   template <typename FromType, typename ToType>
operator ()google::protobuf::__anon4db4a9580311::OneofFieldMover523   void operator()(const FieldDescriptor* field, FromType* from, ToType* to) {
524     switch (field->cpp_type()) {
525       case FieldDescriptor::CPPTYPE_INT32:
526         to->SetInt32(from->GetInt32());
527         break;
528       case FieldDescriptor::CPPTYPE_INT64:
529         to->SetInt64(from->GetInt64());
530         break;
531       case FieldDescriptor::CPPTYPE_UINT32:
532         to->SetUint32(from->GetUint32());
533         break;
534       case FieldDescriptor::CPPTYPE_UINT64:
535         to->SetUint64(from->GetUint64());
536         break;
537       case FieldDescriptor::CPPTYPE_FLOAT:
538         to->SetFloat(from->GetFloat());
539         break;
540       case FieldDescriptor::CPPTYPE_DOUBLE:
541         to->SetDouble(from->GetDouble());
542         break;
543       case FieldDescriptor::CPPTYPE_BOOL:
544         to->SetBool(from->GetBool());
545         break;
546       case FieldDescriptor::CPPTYPE_ENUM:
547         to->SetEnum(from->GetEnum());
548         break;
549       case FieldDescriptor::CPPTYPE_MESSAGE:
550         if (!unsafe_shallow_swap) {
551           to->SetMessage(from->GetMessage());
552         } else {
553           to->UnsafeSetMessage(from->UnsafeGetMessage());
554         }
555         break;
556       case FieldDescriptor::CPPTYPE_STRING:
557         if (!unsafe_shallow_swap) {
558           to->SetString(from->GetString());
559           break;
560         }
561         switch (field->cpp_string_type()) {
562           case FieldDescriptor::CppStringType::kCord:
563             to->SetCord(from->GetCord());
564             break;
565           case FieldDescriptor::CppStringType::kView:
566           case FieldDescriptor::CppStringType::kString:
567             to->SetArenaStringPtr(from->GetArenaStringPtr());
568             break;
569         }
570         break;
571       default:
572         ABSL_LOG(FATAL) << "unimplemented type: " << field->cpp_type();
573     }
574     if (unsafe_shallow_swap) {
575       // Not clearing oneof case after move may cause unwanted "ClearOneof"
576       // where the residual message or string value is deleted and causes
577       // use-after-free (only for unsafe swap).
578       from->ClearOneofCase();
579     }
580   }
581 };
582 
583 }  // namespace
584 
585 namespace internal {
586 
587 class SwapFieldHelper {
588  public:
589   template <bool unsafe_shallow_swap>
590   static void SwapRepeatedStringField(const Reflection* r, Message* lhs,
591                                       Message* rhs,
592                                       const FieldDescriptor* field);
593 
594   template <bool unsafe_shallow_swap>
595   static void SwapInlinedStrings(const Reflection* r, Message* lhs,
596                                  Message* rhs, const FieldDescriptor* field);
597 
598   template <bool unsafe_shallow_swap>
599   static void SwapNonInlinedStrings(const Reflection* r, Message* lhs,
600                                     Message* rhs, const FieldDescriptor* field);
601 
602   template <bool unsafe_shallow_swap>
603   static void SwapStringField(const Reflection* r, Message* lhs, Message* rhs,
604                               const FieldDescriptor* field);
605 
606   static void SwapArenaStringPtr(ArenaStringPtr* lhs, Arena* lhs_arena,
607                                  ArenaStringPtr* rhs, Arena* rhs_arena);
608 
609   template <bool unsafe_shallow_swap>
610   static void SwapRepeatedMessageField(const Reflection* r, Message* lhs,
611                                        Message* rhs,
612                                        const FieldDescriptor* field);
613 
614   template <bool unsafe_shallow_swap>
615   static void SwapMessageField(const Reflection* r, Message* lhs, Message* rhs,
616                                const FieldDescriptor* field);
617 
618   static void SwapMessage(const Reflection* r, Message* lhs, Arena* lhs_arena,
619                           Message* rhs, Arena* rhs_arena,
620                           const FieldDescriptor* field);
621 
622   static void SwapNonMessageNonStringField(const Reflection* r, Message* lhs,
623                                            Message* rhs,
624                                            const FieldDescriptor* field);
625 };
626 
627 template <bool unsafe_shallow_swap>
SwapRepeatedStringField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)628 void SwapFieldHelper::SwapRepeatedStringField(const Reflection* r, Message* lhs,
629                                               Message* rhs,
630                                               const FieldDescriptor* field) {
631   switch (field->cpp_string_type()) {
632     case FieldDescriptor::CppStringType::kCord: {
633       auto* lhs_cord = r->MutableRaw<RepeatedField<absl::Cord>>(lhs, field);
634       auto* rhs_cord = r->MutableRaw<RepeatedField<absl::Cord>>(rhs, field);
635       if (unsafe_shallow_swap) {
636         lhs_cord->InternalSwap(rhs_cord);
637       } else {
638         lhs_cord->Swap(rhs_cord);
639       }
640       break;
641     }
642     case FieldDescriptor::CppStringType::kView:
643     case FieldDescriptor::CppStringType::kString: {
644       auto* lhs_string = r->MutableRaw<RepeatedPtrFieldBase>(lhs, field);
645       auto* rhs_string = r->MutableRaw<RepeatedPtrFieldBase>(rhs, field);
646       if (unsafe_shallow_swap) {
647         lhs_string->InternalSwap(rhs_string);
648       } else {
649         lhs_string->Swap<GenericTypeHandler<std::string>>(rhs_string);
650       }
651       break;
652     }
653   }
654 }
655 
656 template <bool unsafe_shallow_swap>
SwapInlinedStrings(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)657 void SwapFieldHelper::SwapInlinedStrings(const Reflection* r, Message* lhs,
658                                          Message* rhs,
659                                          const FieldDescriptor* field) {
660   // Inlined string field.
661   Arena* lhs_arena = lhs->GetArena();
662   Arena* rhs_arena = rhs->GetArena();
663   auto* lhs_string = r->MutableRaw<InlinedStringField>(lhs, field);
664   auto* rhs_string = r->MutableRaw<InlinedStringField>(rhs, field);
665   uint32_t index = r->schema_.InlinedStringIndex(field);
666   ABSL_DCHECK_GT(index, 0u);
667   uint32_t* lhs_array = r->MutableInlinedStringDonatedArray(lhs);
668   uint32_t* rhs_array = r->MutableInlinedStringDonatedArray(rhs);
669   uint32_t* lhs_state = &lhs_array[index / 32];
670   uint32_t* rhs_state = &rhs_array[index / 32];
671   bool lhs_arena_dtor_registered = (lhs_array[0] & 0x1u) == 0;
672   bool rhs_arena_dtor_registered = (rhs_array[0] & 0x1u) == 0;
673   const uint32_t mask = ~(static_cast<uint32_t>(1) << (index % 32));
674   if (unsafe_shallow_swap) {
675     ABSL_DCHECK_EQ(lhs_arena, rhs_arena);
676     InlinedStringField::InternalSwap(lhs_string, lhs_arena_dtor_registered, lhs,
677                                      rhs_string, rhs_arena_dtor_registered, rhs,
678                                      lhs_arena);
679   } else {
680     const std::string temp = lhs_string->Get();
681     lhs_string->Set(rhs_string->Get(), lhs_arena,
682                     r->IsInlinedStringDonated(*lhs, field), lhs_state, mask,
683                     lhs);
684     rhs_string->Set(temp, rhs_arena, r->IsInlinedStringDonated(*rhs, field),
685                     rhs_state, mask, rhs);
686   }
687 }
688 
689 template <bool unsafe_shallow_swap>
SwapNonInlinedStrings(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)690 void SwapFieldHelper::SwapNonInlinedStrings(const Reflection* r, Message* lhs,
691                                             Message* rhs,
692                                             const FieldDescriptor* field) {
693   ArenaStringPtr* lhs_string = r->MutableRaw<ArenaStringPtr>(lhs, field);
694   ArenaStringPtr* rhs_string = r->MutableRaw<ArenaStringPtr>(rhs, field);
695   if (unsafe_shallow_swap) {
696     ArenaStringPtr::UnsafeShallowSwap(lhs_string, rhs_string);
697   } else {
698     SwapFieldHelper::SwapArenaStringPtr(lhs_string, lhs->GetArena(),  //
699                                         rhs_string, rhs->GetArena());
700   }
701 }
702 
703 template <bool unsafe_shallow_swap>
SwapStringField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)704 void SwapFieldHelper::SwapStringField(const Reflection* r, Message* lhs,
705                                       Message* rhs,
706                                       const FieldDescriptor* field) {
707   switch (field->cpp_string_type()) {
708     case FieldDescriptor::CppStringType::kCord:
709       // Always shallow swap for Cord.
710       std::swap(*r->MutableRaw<absl::Cord>(lhs, field),
711                 *r->MutableRaw<absl::Cord>(rhs, field));
712       break;
713     case FieldDescriptor::CppStringType::kView:
714     case FieldDescriptor::CppStringType::kString: {
715       if (r->IsInlined(field)) {
716         SwapFieldHelper::SwapInlinedStrings<unsafe_shallow_swap>(r, lhs, rhs,
717                                                                  field);
718       } else {
719         SwapFieldHelper::SwapNonInlinedStrings<unsafe_shallow_swap>(r, lhs, rhs,
720                                                                     field);
721       }
722       break;
723     }
724   }
725 }
726 
SwapArenaStringPtr(ArenaStringPtr * lhs,Arena * lhs_arena,ArenaStringPtr * rhs,Arena * rhs_arena)727 void SwapFieldHelper::SwapArenaStringPtr(ArenaStringPtr* lhs, Arena* lhs_arena,
728                                          ArenaStringPtr* rhs,
729                                          Arena* rhs_arena) {
730   if (lhs_arena == rhs_arena) {
731     ArenaStringPtr::InternalSwap(lhs, rhs, lhs_arena);
732   } else if (lhs->IsDefault() && rhs->IsDefault()) {
733     // Nothing to do.
734   } else if (lhs->IsDefault()) {
735     lhs->Set(rhs->Get(), lhs_arena);
736     // rhs needs to be destroyed before overwritten.
737     rhs->Destroy();
738     rhs->InitDefault();
739   } else if (rhs->IsDefault()) {
740     rhs->Set(lhs->Get(), rhs_arena);
741     // lhs needs to be destroyed before overwritten.
742     lhs->Destroy();
743     lhs->InitDefault();
744   } else {
745     std::string temp = lhs->Get();
746     lhs->Set(rhs->Get(), lhs_arena);
747     rhs->Set(std::move(temp), rhs_arena);
748   }
749 }
750 
751 template <bool unsafe_shallow_swap>
SwapRepeatedMessageField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)752 void SwapFieldHelper::SwapRepeatedMessageField(const Reflection* r,
753                                                Message* lhs, Message* rhs,
754                                                const FieldDescriptor* field) {
755   if (IsMapFieldInApi(field)) {
756     auto* lhs_map = r->MutableRaw<MapFieldBase>(lhs, field);
757     auto* rhs_map = r->MutableRaw<MapFieldBase>(rhs, field);
758     if (unsafe_shallow_swap) {
759       lhs_map->UnsafeShallowSwap(rhs_map);
760     } else {
761       lhs_map->Swap(rhs_map);
762     }
763   } else {
764     auto* lhs_rm = r->MutableRaw<RepeatedPtrFieldBase>(lhs, field);
765     auto* rhs_rm = r->MutableRaw<RepeatedPtrFieldBase>(rhs, field);
766     if (unsafe_shallow_swap) {
767       lhs_rm->InternalSwap(rhs_rm);
768     } else {
769       lhs_rm->Swap<GenericTypeHandler<Message>>(rhs_rm);
770     }
771   }
772 }
773 
774 template <bool unsafe_shallow_swap>
SwapMessageField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)775 void SwapFieldHelper::SwapMessageField(const Reflection* r, Message* lhs,
776                                        Message* rhs,
777                                        const FieldDescriptor* field) {
778   if (unsafe_shallow_swap) {
779     std::swap(*r->MutableRaw<Message*>(lhs, field),
780               *r->MutableRaw<Message*>(rhs, field));
781   } else {
782     SwapMessage(r, lhs, lhs->GetArena(), rhs, rhs->GetArena(), field);
783   }
784 }
785 
SwapMessage(const Reflection * r,Message * lhs,Arena * lhs_arena,Message * rhs,Arena * rhs_arena,const FieldDescriptor * field)786 void SwapFieldHelper::SwapMessage(const Reflection* r, Message* lhs,
787                                   Arena* lhs_arena, Message* rhs,
788                                   Arena* rhs_arena,
789                                   const FieldDescriptor* field) {
790   Message** lhs_sub = r->MutableRaw<Message*>(lhs, field);
791   Message** rhs_sub = r->MutableRaw<Message*>(rhs, field);
792 
793   if (*lhs_sub == *rhs_sub) return;
794 
795   if (internal::CanUseInternalSwap(lhs_arena, rhs_arena)) {
796     std::swap(*lhs_sub, *rhs_sub);
797     return;
798   }
799 
800   if (*lhs_sub != nullptr && *rhs_sub != nullptr) {
801     (*lhs_sub)->GetReflection()->Swap(*lhs_sub, *rhs_sub);
802   } else if (*lhs_sub == nullptr && r->HasFieldSingular(*rhs, field)) {
803     *lhs_sub = (*rhs_sub)->New(lhs_arena);
804     (*lhs_sub)->CopyFrom(**rhs_sub);
805     r->ClearField(rhs, field);
806     // Ensures has bit is unchanged after ClearField.
807     r->SetHasBit(rhs, field);
808   } else if (*rhs_sub == nullptr && r->HasFieldSingular(*lhs, field)) {
809     *rhs_sub = (*lhs_sub)->New(rhs_arena);
810     (*rhs_sub)->CopyFrom(**lhs_sub);
811     r->ClearField(lhs, field);
812     // Ensures has bit is unchanged after ClearField.
813     r->SetHasBit(lhs, field);
814   }
815 }
816 
SwapNonMessageNonStringField(const Reflection * r,Message * lhs,Message * rhs,const FieldDescriptor * field)817 void SwapFieldHelper::SwapNonMessageNonStringField(
818     const Reflection* r, Message* lhs, Message* rhs,
819     const FieldDescriptor* field) {
820   switch (field->cpp_type()) {
821 #define SWAP_VALUES(CPPTYPE, TYPE)               \
822   case FieldDescriptor::CPPTYPE_##CPPTYPE:       \
823     std::swap(*r->MutableRaw<TYPE>(lhs, field),  \
824               *r->MutableRaw<TYPE>(rhs, field)); \
825     break;
826 
827     SWAP_VALUES(INT32, int32_t);
828     SWAP_VALUES(INT64, int64_t);
829     SWAP_VALUES(UINT32, uint32_t);
830     SWAP_VALUES(UINT64, uint64_t);
831     SWAP_VALUES(FLOAT, float);
832     SWAP_VALUES(DOUBLE, double);
833     SWAP_VALUES(BOOL, bool);
834     SWAP_VALUES(ENUM, int);
835 #undef SWAP_VALUES
836     default:
837       ABSL_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
838   }
839 }
840 
841 }  // namespace internal
842 
SwapField(Message * message1,Message * message2,const FieldDescriptor * field) const843 void Reflection::SwapField(Message* message1, Message* message2,
844                            const FieldDescriptor* field) const {
845   if (field->is_repeated()) {
846     switch (field->cpp_type()) {
847 #define SWAP_ARRAYS(CPPTYPE, TYPE)                                 \
848   case FieldDescriptor::CPPTYPE_##CPPTYPE:                         \
849     MutableRaw<RepeatedField<TYPE> >(message1, field)              \
850         ->Swap(MutableRaw<RepeatedField<TYPE> >(message2, field)); \
851     break;
852 
853       SWAP_ARRAYS(INT32, int32_t);
854       SWAP_ARRAYS(INT64, int64_t);
855       SWAP_ARRAYS(UINT32, uint32_t);
856       SWAP_ARRAYS(UINT64, uint64_t);
857       SWAP_ARRAYS(FLOAT, float);
858       SWAP_ARRAYS(DOUBLE, double);
859       SWAP_ARRAYS(BOOL, bool);
860       SWAP_ARRAYS(ENUM, int);
861 #undef SWAP_ARRAYS
862 
863       case FieldDescriptor::CPPTYPE_STRING:
864         internal::SwapFieldHelper::SwapRepeatedStringField<false>(
865             this, message1, message2, field);
866         break;
867       case FieldDescriptor::CPPTYPE_MESSAGE:
868         internal::SwapFieldHelper::SwapRepeatedMessageField<false>(
869             this, message1, message2, field);
870         break;
871 
872       default:
873         ABSL_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
874     }
875   } else {
876     switch (field->cpp_type()) {
877       case FieldDescriptor::CPPTYPE_MESSAGE:
878         internal::SwapFieldHelper::SwapMessageField<false>(this, message1,
879                                                            message2, field);
880         break;
881 
882       case FieldDescriptor::CPPTYPE_STRING:
883         internal::SwapFieldHelper::SwapStringField<false>(this, message1,
884                                                           message2, field);
885         break;
886       default:
887         internal::SwapFieldHelper::SwapNonMessageNonStringField(
888             this, message1, message2, field);
889     }
890   }
891 }
892 
UnsafeShallowSwapField(Message * message1,Message * message2,const FieldDescriptor * field) const893 void Reflection::UnsafeShallowSwapField(Message* message1, Message* message2,
894                                         const FieldDescriptor* field) const {
895   if (!field->is_repeated()) {
896     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
897       internal::SwapFieldHelper::SwapMessageField<true>(this, message1,
898                                                         message2, field);
899     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
900       internal::SwapFieldHelper::SwapStringField<true>(this, message1, message2,
901                                                        field);
902     } else {
903       internal::SwapFieldHelper::SwapNonMessageNonStringField(this, message1,
904                                                               message2, field);
905     }
906     return;
907   }
908 
909   switch (field->cpp_type()) {
910 #define SHALLOW_SWAP_ARRAYS(CPPTYPE, TYPE)                                \
911   case FieldDescriptor::CPPTYPE_##CPPTYPE:                                \
912     MutableRaw<RepeatedField<TYPE>>(message1, field)                      \
913         ->InternalSwap(MutableRaw<RepeatedField<TYPE>>(message2, field)); \
914     break;
915 
916     SHALLOW_SWAP_ARRAYS(INT32, int32_t);
917     SHALLOW_SWAP_ARRAYS(INT64, int64_t);
918     SHALLOW_SWAP_ARRAYS(UINT32, uint32_t);
919     SHALLOW_SWAP_ARRAYS(UINT64, uint64_t);
920     SHALLOW_SWAP_ARRAYS(FLOAT, float);
921     SHALLOW_SWAP_ARRAYS(DOUBLE, double);
922     SHALLOW_SWAP_ARRAYS(BOOL, bool);
923     SHALLOW_SWAP_ARRAYS(ENUM, int);
924 #undef SHALLOW_SWAP_ARRAYS
925 
926     case FieldDescriptor::CPPTYPE_STRING:
927       internal::SwapFieldHelper::SwapRepeatedStringField<true>(this, message1,
928                                                                message2, field);
929       break;
930     case FieldDescriptor::CPPTYPE_MESSAGE:
931       internal::SwapFieldHelper::SwapRepeatedMessageField<true>(
932           this, message1, message2, field);
933       break;
934 
935     default:
936       ABSL_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
937   }
938 }
939 
940 // Swaps oneof field between lhs and rhs. If unsafe_shallow_swap is true, it
941 // directly swaps oneof values; otherwise, it may involve copy/delete. Note that
942 // two messages may have different oneof cases. So, it has to be done in three
943 // steps (i.e. lhs -> temp, rhs -> lhs, temp -> rhs).
944 template <bool unsafe_shallow_swap>
SwapOneofField(Message * lhs,Message * rhs,const OneofDescriptor * oneof_descriptor) const945 void Reflection::SwapOneofField(Message* lhs, Message* rhs,
946                                 const OneofDescriptor* oneof_descriptor) const {
947   // Wraps a local variable to temporarily store oneof value.
948   struct LocalVarWrapper {
949 #define LOCAL_VAR_ACCESSOR(type, var, name)               \
950   type Get##name() const { return oneof_val.type_##var; } \
951   void Set##name(type v) { oneof_val.type_##var = v; }
952 
953     LOCAL_VAR_ACCESSOR(int32_t, int32, Int32);
954     LOCAL_VAR_ACCESSOR(int64_t, int64, Int64);
955     LOCAL_VAR_ACCESSOR(uint32_t, uint32, Uint32);
956     LOCAL_VAR_ACCESSOR(uint64_t, uint64, Uint64);
957     LOCAL_VAR_ACCESSOR(float, float, Float);
958     LOCAL_VAR_ACCESSOR(double, double, Double);
959     LOCAL_VAR_ACCESSOR(bool, bool, Bool);
960     LOCAL_VAR_ACCESSOR(int, enum, Enum);
961     LOCAL_VAR_ACCESSOR(Message*, message, Message);
962     LOCAL_VAR_ACCESSOR(ArenaStringPtr, arena_string_ptr, ArenaStringPtr);
963     LOCAL_VAR_ACCESSOR(absl::Cord*, cord, Cord);
964     const std::string& GetString() const { return string_val; }
965     void SetString(const std::string& v) { string_val = v; }
966     Message* UnsafeGetMessage() const { return GetMessage(); }
967     void UnsafeSetMessage(Message* v) { SetMessage(v); }
968     void ClearOneofCase() {}
969 
970     union {
971       int32_t type_int32;
972       int64_t type_int64;
973       uint32_t type_uint32;
974       uint64_t type_uint64;
975       float type_float;
976       double type_double;
977       bool type_bool;
978       int type_enum;
979       Message* type_message;
980       internal::ArenaStringPtr type_arena_string_ptr;
981       absl::Cord* type_cord;
982     } oneof_val;
983 
984     // std::string cannot be in union.
985     std::string string_val;
986   };
987 
988   // Wraps a message pointer to read and write a field.
989   struct MessageWrapper {
990 #define MESSAGE_FIELD_ACCESSOR(type, var, name)         \
991   type Get##name() const {                              \
992     return reflection->GetField<type>(*message, field); \
993   }                                                     \
994   void Set##name(type v) { reflection->SetField<type>(message, field, v); }
995 
996     MESSAGE_FIELD_ACCESSOR(int32_t, int32, Int32);
997     MESSAGE_FIELD_ACCESSOR(int64_t, int64, Int64);
998     MESSAGE_FIELD_ACCESSOR(uint32_t, uint32, Uint32);
999     MESSAGE_FIELD_ACCESSOR(uint64_t, uint64, Uint64);
1000     MESSAGE_FIELD_ACCESSOR(float, float, Float);
1001     MESSAGE_FIELD_ACCESSOR(double, double, Double);
1002     MESSAGE_FIELD_ACCESSOR(bool, bool, Bool);
1003     MESSAGE_FIELD_ACCESSOR(int, enum, Enum);
1004     MESSAGE_FIELD_ACCESSOR(ArenaStringPtr, arena_string_ptr, ArenaStringPtr);
1005     MESSAGE_FIELD_ACCESSOR(absl::Cord*, cord, Cord);
1006     std::string GetString() const {
1007       return reflection->GetString(*message, field);
1008     }
1009     void SetString(const std::string& v) {
1010       reflection->SetString(message, field, v);
1011     }
1012     Message* GetMessage() const {
1013       return reflection->ReleaseMessage(message, field);
1014     }
1015     void SetMessage(Message* v) {
1016       reflection->SetAllocatedMessage(message, v, field);
1017     }
1018     Message* UnsafeGetMessage() const {
1019       return reflection->UnsafeArenaReleaseMessage(message, field);
1020     }
1021     void UnsafeSetMessage(Message* v) {
1022       reflection->UnsafeArenaSetAllocatedMessage(message, v, field);
1023     }
1024     void ClearOneofCase() {
1025       *reflection->MutableOneofCase(message, field->containing_oneof()) = 0;
1026     }
1027 
1028     const Reflection* reflection;
1029     Message* message;
1030     const FieldDescriptor* field;
1031   };
1032 
1033   ABSL_DCHECK(!oneof_descriptor->is_synthetic());
1034   uint32_t oneof_case_lhs = GetOneofCase(*lhs, oneof_descriptor);
1035   uint32_t oneof_case_rhs = GetOneofCase(*rhs, oneof_descriptor);
1036 
1037   LocalVarWrapper temp;
1038   MessageWrapper lhs_wrapper, rhs_wrapper;
1039   const FieldDescriptor* field_lhs = nullptr;
1040   OneofFieldMover<unsafe_shallow_swap> mover;
1041   // lhs --> temp
1042   if (oneof_case_lhs > 0) {
1043     field_lhs = descriptor_->FindFieldByNumber(oneof_case_lhs);
1044     lhs_wrapper = {this, lhs, field_lhs};
1045     mover(field_lhs, &lhs_wrapper, &temp);
1046   }
1047   // rhs --> lhs
1048   if (oneof_case_rhs > 0) {
1049     const FieldDescriptor* f = descriptor_->FindFieldByNumber(oneof_case_rhs);
1050     lhs_wrapper = {this, lhs, f};
1051     rhs_wrapper = {this, rhs, f};
1052     mover(f, &rhs_wrapper, &lhs_wrapper);
1053   } else if (!unsafe_shallow_swap) {
1054     ClearOneof(lhs, oneof_descriptor);
1055   }
1056   // temp --> rhs
1057   if (oneof_case_lhs > 0) {
1058     rhs_wrapper = {this, rhs, field_lhs};
1059     mover(field_lhs, &temp, &rhs_wrapper);
1060   } else if (!unsafe_shallow_swap) {
1061     ClearOneof(rhs, oneof_descriptor);
1062   }
1063 
1064   if (unsafe_shallow_swap) {
1065     *MutableOneofCase(lhs, oneof_descriptor) = oneof_case_rhs;
1066     *MutableOneofCase(rhs, oneof_descriptor) = oneof_case_lhs;
1067   }
1068 }
1069 
Swap(Message * lhs,Message * rhs) const1070 void Reflection::Swap(Message* lhs, Message* rhs) const {
1071   if (lhs == rhs) return;
1072 
1073   Arena* lhs_arena = lhs->GetArena();
1074   Arena* rhs_arena = rhs->GetArena();
1075 
1076   // TODO:  Other Reflection methods should probably check this too.
1077   ABSL_CHECK_EQ(lhs->GetReflection(), this)
1078       << "First argument to Swap() (of type \""
1079       << lhs->GetDescriptor()->full_name()
1080       << "\") is not compatible with this reflection object (which is for type "
1081          "\""
1082       << descriptor_->full_name()
1083       << "\").  Note that the exact same class is required; not just the same "
1084          "descriptor.";
1085   ABSL_CHECK_EQ(rhs->GetReflection(), this)
1086       << "Second argument to Swap() (of type \""
1087       << rhs->GetDescriptor()->full_name()
1088       << "\") is not compatible with this reflection object (which is for type "
1089          "\""
1090       << descriptor_->full_name()
1091       << "\").  Note that the exact same class is required; not just the same "
1092          "descriptor.";
1093 
1094   // Check that both messages are in the same arena (or both on the heap). We
1095   // need to copy all data if not, due to ownership semantics.
1096   if (!internal::CanUseInternalSwap(lhs_arena, rhs_arena)) {
1097     // One of the two is guaranteed to have an arena.  Switch things around
1098     // to guarantee that lhs has an arena.
1099     Arena* arena = lhs_arena;
1100     if (arena == nullptr) {
1101       arena = rhs_arena;
1102       std::swap(lhs, rhs);  // Swapping names for pointers!
1103     }
1104 
1105     Message* temp = lhs->New(arena);
1106     temp->MergeFrom(*rhs);
1107     rhs->CopyFrom(*lhs);
1108     if (internal::DebugHardenForceCopyInSwap()) {
1109       lhs->CopyFrom(*temp);
1110       if (arena == nullptr) delete temp;
1111     } else {
1112       Swap(lhs, temp);
1113     }
1114     return;
1115   }
1116 
1117   UnsafeArenaSwap(lhs, rhs);
1118 }
1119 
1120 template <bool unsafe_shallow_swap>
SwapFieldsImpl(Message * message1,Message * message2,const std::vector<const FieldDescriptor * > & fields) const1121 void Reflection::SwapFieldsImpl(
1122     Message* message1, Message* message2,
1123     const std::vector<const FieldDescriptor*>& fields) const {
1124   if (message1 == message2) return;
1125 
1126   // TODO:  Other Reflection methods should probably check this too.
1127   ABSL_CHECK_EQ(message1->GetReflection(), this)
1128       << "First argument to SwapFields() (of type \""
1129       << message1->GetDescriptor()->full_name()
1130       << "\") is not compatible with this reflection object (which is for type "
1131          "\""
1132       << descriptor_->full_name()
1133       << "\").  Note that the exact same class is required; not just the same "
1134          "descriptor.";
1135   ABSL_CHECK_EQ(message2->GetReflection(), this)
1136       << "Second argument to SwapFields() (of type \""
1137       << message2->GetDescriptor()->full_name()
1138       << "\") is not compatible with this reflection object (which is for type "
1139          "\""
1140       << descriptor_->full_name()
1141       << "\").  Note that the exact same class is required; not just the same "
1142          "descriptor.";
1143 
1144   absl::flat_hash_set<int> swapped_oneof;
1145 
1146   const Message* prototype =
1147       message_factory_->GetPrototype(message1->GetDescriptor());
1148   for (const auto* field : fields) {
1149     if (field->is_extension()) {
1150       if (unsafe_shallow_swap) {
1151         MutableExtensionSet(message1)->UnsafeShallowSwapExtension(
1152             MutableExtensionSet(message2), field->number());
1153       } else {
1154         MutableExtensionSet(message1)->SwapExtension(
1155             prototype, MutableExtensionSet(message2), field->number());
1156       }
1157     } else {
1158       if (schema_.InRealOneof(field)) {
1159         int oneof_index = field->containing_oneof()->index();
1160         // Only swap the oneof field once.
1161         if (!swapped_oneof.insert(oneof_index).second) {
1162           continue;
1163         }
1164         SwapOneofField<unsafe_shallow_swap>(message1, message2,
1165                                             field->containing_oneof());
1166       } else {
1167         // Swap field.
1168         if (unsafe_shallow_swap) {
1169           UnsafeShallowSwapField(message1, message2, field);
1170         } else {
1171           SwapField(message1, message2, field);
1172         }
1173         // Swap has bit for non-repeated fields.  We have already checked for
1174         // oneof already. This has to be done after SwapField, because SwapField
1175         // may depend on the information in has bits.
1176         if (!field->is_repeated()) {
1177           SwapHasBit(message1, message2, field);
1178           if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
1179               field->cpp_string_type() ==
1180                   FieldDescriptor::CppStringType::kString &&
1181               IsInlined(field)) {
1182             ABSL_DCHECK(!unsafe_shallow_swap ||
1183                         message1->GetArena() == message2->GetArena());
1184             SwapInlinedStringDonated(message1, message2, field);
1185           }
1186         }
1187       }
1188     }
1189   }
1190 }
1191 
1192 template void Reflection::SwapFieldsImpl<true>(
1193     Message* message1, Message* message2,
1194     const std::vector<const FieldDescriptor*>& fields) const;
1195 
1196 template void Reflection::SwapFieldsImpl<false>(
1197     Message* message1, Message* message2,
1198     const std::vector<const FieldDescriptor*>& fields) const;
1199 
SwapFields(Message * message1,Message * message2,const std::vector<const FieldDescriptor * > & fields) const1200 void Reflection::SwapFields(
1201     Message* message1, Message* message2,
1202     const std::vector<const FieldDescriptor*>& fields) const {
1203   SwapFieldsImpl<false>(message1, message2, fields);
1204 }
1205 
UnsafeShallowSwapFields(Message * message1,Message * message2,const std::vector<const FieldDescriptor * > & fields) const1206 void Reflection::UnsafeShallowSwapFields(
1207     Message* message1, Message* message2,
1208     const std::vector<const FieldDescriptor*>& fields) const {
1209   ABSL_DCHECK_EQ(message1->GetArena(), message2->GetArena());
1210 
1211   SwapFieldsImpl<true>(message1, message2, fields);
1212 }
1213 
UnsafeArenaSwapFields(Message * lhs,Message * rhs,const std::vector<const FieldDescriptor * > & fields) const1214 void Reflection::UnsafeArenaSwapFields(
1215     Message* lhs, Message* rhs,
1216     const std::vector<const FieldDescriptor*>& fields) const {
1217   ABSL_DCHECK_EQ(lhs->GetArena(), rhs->GetArena());
1218   UnsafeShallowSwapFields(lhs, rhs, fields);
1219 }
1220 
1221 // -------------------------------------------------------------------
1222 
HasField(const Message & message,const FieldDescriptor * field) const1223 bool Reflection::HasField(const Message& message,
1224                           const FieldDescriptor* field) const {
1225   USAGE_CHECK_MESSAGE(HasField, &message);
1226   USAGE_CHECK_MESSAGE_TYPE(HasField);
1227   USAGE_CHECK_SINGULAR(HasField);
1228 
1229   if (field->is_extension()) {
1230     return GetExtensionSet(message).Has(field->number());
1231   } else {
1232     if (schema_.InRealOneof(field)) {
1233       return HasOneofField(message, field);
1234     } else {
1235       return HasFieldSingular(message, field);
1236     }
1237   }
1238 }
1239 
UnsafeArenaSwap(Message * lhs,Message * rhs) const1240 void Reflection::UnsafeArenaSwap(Message* lhs, Message* rhs) const {
1241   ABSL_DCHECK_EQ(lhs->GetArena(), rhs->GetArena());
1242   InternalSwap(lhs, rhs);
1243 }
1244 
InternalSwap(Message * lhs,Message * rhs) const1245 void Reflection::InternalSwap(Message* lhs, Message* rhs) const {
1246   if (lhs == rhs) return;
1247 
1248   MutableInternalMetadata(lhs)->InternalSwap(MutableInternalMetadata(rhs));
1249 
1250   for (int i = 0; i <= last_non_weak_field_index_; i++) {
1251     const FieldDescriptor* field = descriptor_->field(i);
1252     if (schema_.InRealOneof(field)) continue;
1253     if (schema_.IsSplit(field)) {
1254       continue;
1255     }
1256     UnsafeShallowSwapField(lhs, rhs, field);
1257   }
1258   if (schema_.IsSplit()) {
1259     std::swap(*MutableSplitField(lhs), *MutableSplitField(rhs));
1260   }
1261   const int oneof_decl_count = descriptor_->real_oneof_decl_count();
1262   for (int i = 0; i < oneof_decl_count; i++) {
1263     const OneofDescriptor* oneof = descriptor_->real_oneof_decl(i);
1264     SwapOneofField<true>(lhs, rhs, oneof);
1265   }
1266 
1267   // Swapping bits need to happen after swapping fields, because the latter may
1268   // depend on the has bit information.
1269   if (schema_.HasHasbits()) {
1270     uint32_t* lhs_has_bits = MutableHasBits(lhs);
1271     uint32_t* rhs_has_bits = MutableHasBits(rhs);
1272 
1273     int fields_with_has_bits = 0;
1274     for (int i = 0; i < descriptor_->field_count(); i++) {
1275       const FieldDescriptor* field = descriptor_->field(i);
1276       if (internal::cpp::HasHasbit(field)) {
1277         ++fields_with_has_bits;
1278       }
1279     }
1280 
1281     int has_bits_size = (fields_with_has_bits + 31) / 32;
1282 
1283     for (int i = 0; i < has_bits_size; i++) {
1284       std::swap(lhs_has_bits[i], rhs_has_bits[i]);
1285     }
1286   }
1287 
1288   if (schema_.HasInlinedString()) {
1289     uint32_t* lhs_donated_array = MutableInlinedStringDonatedArray(lhs);
1290     uint32_t* rhs_donated_array = MutableInlinedStringDonatedArray(rhs);
1291     int inlined_string_count = 0;
1292     for (int i = 0; i < descriptor_->field_count(); i++) {
1293       const FieldDescriptor* field = descriptor_->field(i);
1294       if (field->cpp_type() != FieldDescriptor::CPPTYPE_STRING) continue;
1295       if (field->is_extension() || field->is_repeated() ||
1296           schema_.InRealOneof(field) ||
1297           field->cpp_string_type() != FieldDescriptor::CppStringType::kString ||
1298           !IsInlined(field)) {
1299         continue;
1300       }
1301       inlined_string_count++;
1302     }
1303 
1304     int donated_array_size = inlined_string_count == 0
1305                                  ? 0
1306                                  // One extra bit for the arena dtor tracking.
1307                                  : (inlined_string_count + 1 + 31) / 32;
1308     ABSL_CHECK_EQ((lhs_donated_array[0] & 0x1u) == 0,
1309                   (rhs_donated_array[0] & 0x1u) == 0);
1310     for (int i = 0; i < donated_array_size; i++) {
1311       std::swap(lhs_donated_array[i], rhs_donated_array[i]);
1312     }
1313   }
1314 
1315   if (schema_.HasExtensionSet()) {
1316     MutableExtensionSet(lhs)->InternalSwap(MutableExtensionSet(rhs));
1317   }
1318 }
1319 
MaybePoisonAfterClear(Message & root) const1320 void Reflection::MaybePoisonAfterClear(Message& root) const {
1321   root.Clear();
1322 }
1323 
FieldSize(const Message & message,const FieldDescriptor * field) const1324 int Reflection::FieldSize(const Message& message,
1325                           const FieldDescriptor* field) const {
1326   USAGE_CHECK_MESSAGE(FieldSize, &message);
1327   USAGE_CHECK_MESSAGE_TYPE(FieldSize);
1328   USAGE_CHECK_REPEATED(FieldSize);
1329 
1330   if (field->is_extension()) {
1331     return GetExtensionSet(message).ExtensionSize(field->number());
1332   } else {
1333     switch (field->cpp_type()) {
1334 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)    \
1335   case FieldDescriptor::CPPTYPE_##UPPERCASE: \
1336     return GetRaw<RepeatedField<LOWERCASE> >(message, field).size()
1337 
1338       HANDLE_TYPE(INT32, int32_t);
1339       HANDLE_TYPE(INT64, int64_t);
1340       HANDLE_TYPE(UINT32, uint32_t);
1341       HANDLE_TYPE(UINT64, uint64_t);
1342       HANDLE_TYPE(DOUBLE, double);
1343       HANDLE_TYPE(FLOAT, float);
1344       HANDLE_TYPE(BOOL, bool);
1345       HANDLE_TYPE(ENUM, int);
1346 #undef HANDLE_TYPE
1347 
1348       case FieldDescriptor::CPPTYPE_STRING:
1349         if (field->cpp_string_type() == FieldDescriptor::CppStringType::kCord) {
1350           return GetRaw<RepeatedField<absl::Cord> >(message, field).size();
1351         }
1352         ABSL_FALLTHROUGH_INTENDED;
1353       case FieldDescriptor::CPPTYPE_MESSAGE:
1354         if (IsMapFieldInApi(field)) {
1355           const internal::MapFieldBase& map =
1356               GetRaw<MapFieldBase>(message, field);
1357           if (map.IsRepeatedFieldValid()) {
1358             return map.GetRepeatedField().size();
1359           } else {
1360             // No need to materialize the repeated field if it is out of sync:
1361             // its size will be the same as the map's size.
1362             return map.size();
1363           }
1364         } else {
1365           return GetRaw<RepeatedPtrFieldBase>(message, field).size();
1366         }
1367     }
1368 
1369     ABSL_LOG(FATAL) << "Can't get here.";
1370     return 0;
1371   }
1372 }
1373 
ClearField(Message * message,const FieldDescriptor * field) const1374 void Reflection::ClearField(Message* message,
1375                             const FieldDescriptor* field) const {
1376   USAGE_CHECK_MESSAGE(ClearField, message);
1377   USAGE_CHECK_MESSAGE_TYPE(ClearField);
1378 
1379   if (field->is_extension()) {
1380     MutableExtensionSet(message)->ClearExtension(field->number());
1381   } else if (!field->is_repeated()) {
1382     if (schema_.InRealOneof(field)) {
1383       ClearOneofField(message, field);
1384       return;
1385     }
1386     if (HasFieldSingular(*message, field)) {
1387       ClearHasBit(message, field);
1388 
1389       // We need to set the field back to its default value.
1390       switch (field->cpp_type()) {
1391 #define CLEAR_TYPE(CPPTYPE, TYPE)                                      \
1392   case FieldDescriptor::CPPTYPE_##CPPTYPE:                             \
1393     *MutableRaw<TYPE>(message, field) = field->default_value_##TYPE(); \
1394     break;
1395 
1396         CLEAR_TYPE(INT32, int32_t);
1397         CLEAR_TYPE(INT64, int64_t);
1398         CLEAR_TYPE(UINT32, uint32_t);
1399         CLEAR_TYPE(UINT64, uint64_t);
1400         CLEAR_TYPE(FLOAT, float);
1401         CLEAR_TYPE(DOUBLE, double);
1402         CLEAR_TYPE(BOOL, bool);
1403 #undef CLEAR_TYPE
1404 
1405         case FieldDescriptor::CPPTYPE_ENUM:
1406           *MutableRaw<int>(message, field) =
1407               field->default_value_enum()->number();
1408           break;
1409 
1410         case FieldDescriptor::CPPTYPE_STRING: {
1411           switch (field->cpp_string_type()) {
1412             case FieldDescriptor::CppStringType::kCord:
1413               if (field->has_default_value()) {
1414                 *MutableRaw<absl::Cord>(message, field) =
1415                     field->default_value_string();
1416               } else {
1417                 MutableRaw<absl::Cord>(message, field)->Clear();
1418               }
1419               break;
1420             case FieldDescriptor::CppStringType::kView:
1421             case FieldDescriptor::CppStringType::kString:
1422               if (IsInlined(field)) {
1423                 // Currently, string with default value can't be inlined. So we
1424                 // don't have to handle default value here.
1425                 MutableRaw<InlinedStringField>(message, field)->ClearToEmpty();
1426               } else {
1427                 auto* str = MutableRaw<ArenaStringPtr>(message, field);
1428                 str->Destroy();
1429                 str->InitDefault();
1430               }
1431               break;
1432           }
1433           break;
1434         }
1435 
1436         case FieldDescriptor::CPPTYPE_MESSAGE:
1437           if (schema_.HasBitIndex(field) == static_cast<uint32_t>(-1)) {
1438             // Proto3 does not have has-bits and we need to set a message field
1439             // to nullptr in order to indicate its un-presence.
1440             if (message->GetArena() == nullptr) {
1441               delete *MutableRaw<Message*>(message, field);
1442             }
1443             *MutableRaw<Message*>(message, field) = nullptr;
1444           } else {
1445             (*MutableRaw<Message*>(message, field))->Clear();
1446           }
1447           break;
1448       }
1449     }
1450   } else {
1451     switch (field->cpp_type()) {
1452 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                           \
1453   case FieldDescriptor::CPPTYPE_##UPPERCASE:                        \
1454     MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear(); \
1455     break
1456 
1457       HANDLE_TYPE(INT32, int32_t);
1458       HANDLE_TYPE(INT64, int64_t);
1459       HANDLE_TYPE(UINT32, uint32_t);
1460       HANDLE_TYPE(UINT64, uint64_t);
1461       HANDLE_TYPE(DOUBLE, double);
1462       HANDLE_TYPE(FLOAT, float);
1463       HANDLE_TYPE(BOOL, bool);
1464       HANDLE_TYPE(ENUM, int);
1465 #undef HANDLE_TYPE
1466 
1467       case FieldDescriptor::CPPTYPE_STRING: {
1468         switch (field->cpp_string_type()) {
1469           case FieldDescriptor::CppStringType::kCord:
1470             MutableRaw<RepeatedField<absl::Cord>>(message, field)->Clear();
1471             break;
1472           case FieldDescriptor::CppStringType::kView:
1473           case FieldDescriptor::CppStringType::kString:
1474             MutableRaw<RepeatedPtrField<std::string> >(message, field)->Clear();
1475             break;
1476         }
1477         break;
1478       }
1479 
1480       case FieldDescriptor::CPPTYPE_MESSAGE: {
1481         if (IsMapFieldInApi(field)) {
1482           MutableRaw<MapFieldBase>(message, field)->Clear();
1483         } else {
1484           // We don't know which subclass of RepeatedPtrFieldBase the type is,
1485           // so we use RepeatedPtrFieldBase directly.
1486           MutableRaw<RepeatedPtrFieldBase>(message, field)
1487               ->Clear<GenericTypeHandler<Message> >();
1488         }
1489         break;
1490       }
1491     }
1492   }
1493 }
1494 
RemoveLast(Message * message,const FieldDescriptor * field) const1495 void Reflection::RemoveLast(Message* message,
1496                             const FieldDescriptor* field) const {
1497   USAGE_CHECK_MESSAGE(RemoveLast, message);
1498   USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
1499   USAGE_CHECK_REPEATED(RemoveLast);
1500 
1501   if (field->is_extension()) {
1502     MutableExtensionSet(message)->RemoveLast(field->number());
1503   } else {
1504     switch (field->cpp_type()) {
1505 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                \
1506   case FieldDescriptor::CPPTYPE_##UPPERCASE:                             \
1507     MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast(); \
1508     break
1509 
1510       HANDLE_TYPE(INT32, int32_t);
1511       HANDLE_TYPE(INT64, int64_t);
1512       HANDLE_TYPE(UINT32, uint32_t);
1513       HANDLE_TYPE(UINT64, uint64_t);
1514       HANDLE_TYPE(DOUBLE, double);
1515       HANDLE_TYPE(FLOAT, float);
1516       HANDLE_TYPE(BOOL, bool);
1517       HANDLE_TYPE(ENUM, int);
1518 #undef HANDLE_TYPE
1519 
1520       case FieldDescriptor::CPPTYPE_STRING:
1521         switch (field->cpp_string_type()) {
1522           case FieldDescriptor::CppStringType::kCord:
1523             MutableRaw<RepeatedField<absl::Cord>>(message, field)->RemoveLast();
1524             break;
1525           case FieldDescriptor::CppStringType::kView:
1526           case FieldDescriptor::CppStringType::kString:
1527             MutableRaw<RepeatedPtrField<std::string> >(message, field)
1528                 ->RemoveLast();
1529             break;
1530         }
1531         break;
1532 
1533       case FieldDescriptor::CPPTYPE_MESSAGE:
1534         if (IsMapFieldInApi(field)) {
1535           MutableRaw<MapFieldBase>(message, field)
1536               ->MutableRepeatedField()
1537               ->RemoveLast<GenericTypeHandler<Message> >();
1538         } else {
1539           MutableRaw<RepeatedPtrFieldBase>(message, field)
1540               ->RemoveLast<GenericTypeHandler<Message> >();
1541         }
1542         break;
1543     }
1544   }
1545 }
1546 
ReleaseLast(Message * message,const FieldDescriptor * field) const1547 Message* Reflection::ReleaseLast(Message* message,
1548                                  const FieldDescriptor* field) const {
1549   USAGE_MUTABLE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE);
1550 
1551   Message* released;
1552   if (field->is_extension()) {
1553     released = static_cast<Message*>(
1554         MutableExtensionSet(message)->ReleaseLast(field->number()));
1555   } else {
1556     if (IsMapFieldInApi(field)) {
1557       released = MutableRaw<MapFieldBase>(message, field)
1558                      ->MutableRepeatedField()
1559                      ->ReleaseLast<GenericTypeHandler<Message>>();
1560     } else {
1561       released = MutableRaw<RepeatedPtrFieldBase>(message, field)
1562                      ->ReleaseLast<GenericTypeHandler<Message>>();
1563     }
1564   }
1565   if (internal::DebugHardenForceCopyInRelease()) {
1566     return MaybeForceCopy(message->GetArena(), released);
1567   } else {
1568     return released;
1569   }
1570 }
1571 
UnsafeArenaReleaseLast(Message * message,const FieldDescriptor * field) const1572 Message* Reflection::UnsafeArenaReleaseLast(
1573     Message* message, const FieldDescriptor* field) const {
1574   USAGE_MUTABLE_CHECK_ALL(UnsafeArenaReleaseLast, REPEATED, MESSAGE);
1575 
1576   if (field->is_extension()) {
1577     return static_cast<Message*>(
1578         MutableExtensionSet(message)->UnsafeArenaReleaseLast(field->number()));
1579   } else {
1580     if (IsMapFieldInApi(field)) {
1581       return MutableRaw<MapFieldBase>(message, field)
1582           ->MutableRepeatedField()
1583           ->UnsafeArenaReleaseLast<GenericTypeHandler<Message>>();
1584     } else {
1585       return MutableRaw<RepeatedPtrFieldBase>(message, field)
1586           ->UnsafeArenaReleaseLast<GenericTypeHandler<Message>>();
1587     }
1588   }
1589 }
1590 
SwapElements(Message * message,const FieldDescriptor * field,int index1,int index2) const1591 void Reflection::SwapElements(Message* message, const FieldDescriptor* field,
1592                               int index1, int index2) const {
1593   USAGE_CHECK_MESSAGE(Swap, message);
1594   USAGE_CHECK_MESSAGE_TYPE(Swap);
1595   USAGE_CHECK_REPEATED(Swap);
1596 
1597   if (field->is_extension()) {
1598     MutableExtensionSet(message)->SwapElements(field->number(), index1, index2);
1599   } else {
1600     switch (field->cpp_type()) {
1601 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                 \
1602   case FieldDescriptor::CPPTYPE_##UPPERCASE:              \
1603     MutableRaw<RepeatedField<LOWERCASE> >(message, field) \
1604         ->SwapElements(index1, index2);                   \
1605     break
1606 
1607       HANDLE_TYPE(INT32, int32_t);
1608       HANDLE_TYPE(INT64, int64_t);
1609       HANDLE_TYPE(UINT32, uint32_t);
1610       HANDLE_TYPE(UINT64, uint64_t);
1611       HANDLE_TYPE(DOUBLE, double);
1612       HANDLE_TYPE(FLOAT, float);
1613       HANDLE_TYPE(BOOL, bool);
1614       HANDLE_TYPE(ENUM, int);
1615 #undef HANDLE_TYPE
1616 
1617       case FieldDescriptor::CPPTYPE_STRING:
1618         if (field->cpp_string_type() == FieldDescriptor::CppStringType::kCord) {
1619           MutableRaw<RepeatedField<absl::Cord> >(message, field)
1620               ->SwapElements(index1, index2);
1621           break;
1622         }
1623         ABSL_FALLTHROUGH_INTENDED;
1624       case FieldDescriptor::CPPTYPE_MESSAGE:
1625         if (IsMapFieldInApi(field)) {
1626           MutableRaw<MapFieldBase>(message, field)
1627               ->MutableRepeatedField()
1628               ->SwapElements(index1, index2);
1629         } else {
1630           MutableRaw<RepeatedPtrFieldBase>(message, field)
1631               ->SwapElements(index1, index2);
1632         }
1633         break;
1634     }
1635   }
1636 }
1637 
1638 namespace {
1639 // Comparison functor for sorting FieldDescriptors by field number.
1640 struct FieldNumberSorter {
operator ()google::protobuf::__anon4db4a9580511::FieldNumberSorter1641   bool operator()(const FieldDescriptor* left,
1642                   const FieldDescriptor* right) const {
1643     return left->number() < right->number();
1644   }
1645 };
1646 
IsIndexInHasBitSet(const uint32_t * has_bit_set,uint32_t has_bit_index)1647 bool IsIndexInHasBitSet(const uint32_t* has_bit_set, uint32_t has_bit_index) {
1648   ABSL_DCHECK_NE(has_bit_index, ~0u);
1649   return ((has_bit_set[has_bit_index / 32] >> (has_bit_index % 32)) &
1650           static_cast<uint32_t>(1)) != 0;
1651 }
1652 
CheckInOrder(const FieldDescriptor * field,uint32_t * last)1653 void CheckInOrder(const FieldDescriptor* field, uint32_t* last) {
1654   *last = *last <= static_cast<uint32_t>(field->number())
1655               ? static_cast<uint32_t>(field->number())
1656               : UINT32_MAX;
1657 }
1658 
1659 }  // namespace
1660 
1661 namespace internal {
CreateUnknownEnumValues(const FieldDescriptor * field)1662 bool CreateUnknownEnumValues(const FieldDescriptor* field) {
1663   bool open_enum = false;
1664   return !field->legacy_enum_field_treated_as_closed() || open_enum;
1665 }
1666 }  // namespace internal
1667 using internal::CreateUnknownEnumValues;
1668 
ListFields(const Message & message,std::vector<const FieldDescriptor * > * output) const1669 void Reflection::ListFields(const Message& message,
1670                             std::vector<const FieldDescriptor*>* output) const {
1671   output->clear();
1672 
1673   // Optimization:  The default instance never has any fields set.
1674   if (schema_.IsDefaultInstance(message)) return;
1675 
1676   // Optimization: Avoid calling GetHasBits() and HasOneofField() many times
1677   // within the field loop.  We allow this violation of ReflectionSchema
1678   // encapsulation because this function takes a noticeable about of CPU
1679   // fleetwide and properly allowing this optimization through public interfaces
1680   // seems more trouble than it is worth.
1681   const uint32_t* const has_bits =
1682       schema_.HasHasbits() ? GetHasBits(message) : nullptr;
1683   const uint32_t* const has_bits_indices = schema_.has_bit_indices_;
1684   output->reserve(descriptor_->field_count());
1685   const int last_non_weak_field_index = last_non_weak_field_index_;
1686   // Fields in messages are usually added with the increasing tags.
1687   uint32_t last = 0;  // UINT32_MAX if out-of-order
1688   auto append_to_output = [&last, &output](const FieldDescriptor* field) {
1689     CheckInOrder(field, &last);
1690     output->push_back(field);
1691   };
1692   for (int i = 0; i <= last_non_weak_field_index; i++) {
1693     const FieldDescriptor* field = descriptor_->field(i);
1694     if (field->is_repeated()) {
1695       if (FieldSize(message, field) > 0) {
1696         append_to_output(field);
1697       }
1698     } else {
1699       const OneofDescriptor* containing_oneof = field->containing_oneof();
1700       if (schema_.InRealOneof(field)) {
1701         const uint32_t* const oneof_case_array =
1702             GetConstPointerAtOffset<uint32_t>(&message,
1703                                               schema_.oneof_case_offset_);
1704         // Equivalent to: HasOneofField(message, field)
1705         if (static_cast<int64_t>(oneof_case_array[containing_oneof->index()]) ==
1706             field->number()) {
1707           append_to_output(field);
1708         }
1709       } else if (has_bits && has_bits_indices[i] != static_cast<uint32_t>(-1)) {
1710         // Equivalent to: HasFieldSingular(message, field)
1711         if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) {
1712           append_to_output(field);
1713         }
1714       } else if (HasFieldSingular(message, field)) {
1715         // Fall back on proto3-style HasBit.
1716         append_to_output(field);
1717       }
1718     }
1719   }
1720   // Descriptors of ExtensionSet are appended in their increasing tag
1721   // order and they are usually bigger than the field tags so if all fields are
1722   // not sorted, let them be sorted.
1723   if (last == UINT32_MAX) {
1724     std::sort(output->begin(), output->end(), FieldNumberSorter());
1725     last = output->back()->number();
1726   }
1727   size_t last_size = output->size();
1728   if (schema_.HasExtensionSet()) {
1729     // Descriptors of ExtensionSet are appended in their increasing order.
1730     GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
1731                                           output);
1732     ABSL_DCHECK(std::is_sorted(output->begin() + last_size, output->end(),
1733                                FieldNumberSorter()));
1734     if (output->size() != last_size) {
1735       CheckInOrder((*output)[last_size], &last);
1736     }
1737   }
1738   if (last != UINT32_MAX) {
1739     ABSL_DCHECK(
1740         std::is_sorted(output->begin(), output->end(), FieldNumberSorter()));
1741   } else {
1742     // ListFields() must sort output by field number.
1743     std::sort(output->begin(), output->end(), FieldNumberSorter());
1744   }
1745 }
1746 
1747 // -------------------------------------------------------------------
1748 
1749 #undef DEFINE_PRIMITIVE_ACCESSORS
1750 #define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE)          \
1751   PASSTYPE Reflection::Get##TYPENAME(const Message& message,                   \
1752                                      const FieldDescriptor* field) const {     \
1753     USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE);                         \
1754     if (field->is_extension()) {                                               \
1755       return GetExtensionSet(message).Get##TYPENAME(                           \
1756           field->number(), field->default_value_##PASSTYPE());                 \
1757     } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { \
1758       return field->default_value_##PASSTYPE();                                \
1759     } else {                                                                   \
1760       return GetField<TYPE>(message, field);                                   \
1761     }                                                                          \
1762   }                                                                            \
1763                                                                                \
1764   void Reflection::Set##TYPENAME(                                              \
1765       Message* message, const FieldDescriptor* field, PASSTYPE value) const {  \
1766     USAGE_MUTABLE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE);                 \
1767     if (field->is_extension()) {                                               \
1768       return MutableExtensionSet(message)->Set##TYPENAME(                      \
1769           field->number(), field->type(), value, field);                       \
1770     } else {                                                                   \
1771       SetField<TYPE>(message, field, value);                                   \
1772     }                                                                          \
1773   }                                                                            \
1774                                                                                \
1775   PASSTYPE Reflection::GetRepeated##TYPENAME(                                  \
1776       const Message& message, const FieldDescriptor* field, int index) const { \
1777     USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE);                 \
1778     if (field->is_extension()) {                                               \
1779       return GetExtensionSet(message).GetRepeated##TYPENAME(field->number(),   \
1780                                                             index);            \
1781     } else {                                                                   \
1782       return GetRepeatedField<TYPE>(message, field, index);                    \
1783     }                                                                          \
1784   }                                                                            \
1785                                                                                \
1786   void Reflection::SetRepeated##TYPENAME(Message* message,                     \
1787                                          const FieldDescriptor* field,         \
1788                                          int index, PASSTYPE value) const {    \
1789     USAGE_MUTABLE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE);         \
1790     if (field->is_extension()) {                                               \
1791       MutableExtensionSet(message)->SetRepeated##TYPENAME(field->number(),     \
1792                                                           index, value);       \
1793     } else {                                                                   \
1794       SetRepeatedField<TYPE>(message, field, index, value);                    \
1795     }                                                                          \
1796   }                                                                            \
1797                                                                                \
1798   void Reflection::Add##TYPENAME(                                              \
1799       Message* message, const FieldDescriptor* field, PASSTYPE value) const {  \
1800     USAGE_MUTABLE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE);                 \
1801     if (field->is_extension()) {                                               \
1802       MutableExtensionSet(message)->Add##TYPENAME(                             \
1803           field->number(), field->type(), field->is_packed(), value, field);   \
1804     } else {                                                                   \
1805       AddField<TYPE>(message, field, value);                                   \
1806     }                                                                          \
1807   }
1808 
DEFINE_PRIMITIVE_ACCESSORS(Int32,int32_t,int32_t,INT32)1809 DEFINE_PRIMITIVE_ACCESSORS(Int32, int32_t, int32_t, INT32)
1810 DEFINE_PRIMITIVE_ACCESSORS(Int64, int64_t, int64_t, INT64)
1811 DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32_t, uint32_t, UINT32)
1812 DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64_t, uint64_t, UINT64)
1813 DEFINE_PRIMITIVE_ACCESSORS(Float, float, float, FLOAT)
1814 DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE)
1815 DEFINE_PRIMITIVE_ACCESSORS(Bool, bool, bool, BOOL)
1816 #undef DEFINE_PRIMITIVE_ACCESSORS
1817 
1818 // -------------------------------------------------------------------
1819 
1820 std::string Reflection::GetString(const Message& message,
1821                                   const FieldDescriptor* field) const {
1822   USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
1823   if (field->is_extension()) {
1824     return GetExtensionSet(message).GetString(
1825         field->number(), internal::DefaultValueStringAsString(field));
1826   } else {
1827     if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1828       return std::string(field->default_value_string());
1829     }
1830     switch (field->cpp_string_type()) {
1831       case FieldDescriptor::CppStringType::kCord:
1832         if (schema_.InRealOneof(field)) {
1833           return std::string(*GetField<absl::Cord*>(message, field));
1834         } else {
1835           return std::string(GetField<absl::Cord>(message, field));
1836         }
1837       case FieldDescriptor::CppStringType::kView:
1838       case FieldDescriptor::CppStringType::kString:
1839         if (IsInlined(field)) {
1840           return GetField<InlinedStringField>(message, field).GetNoArena();
1841         } else {
1842           const auto& str = GetField<ArenaStringPtr>(message, field);
1843           return str.IsDefault() ? std::string(field->default_value_string())
1844                                  : str.Get();
1845         }
1846     }
1847     internal::Unreachable();
1848   }
1849 }
1850 
GetStringReference(const Message & message,const FieldDescriptor * field,std::string * scratch) const1851 const std::string& Reflection::GetStringReference(const Message& message,
1852                                                   const FieldDescriptor* field,
1853                                                   std::string* scratch) const {
1854   (void)scratch;  // Parameter is used by Google-internal code.
1855   USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
1856   if (field->is_extension()) {
1857     return GetExtensionSet(message).GetString(
1858         field->number(), internal::DefaultValueStringAsString(field));
1859   } else {
1860     if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1861       return internal::DefaultValueStringAsString(field);
1862     }
1863     switch (field->cpp_string_type()) {
1864       case FieldDescriptor::CppStringType::kCord:
1865         if (schema_.InRealOneof(field)) {
1866           absl::CopyCordToString(*GetField<absl::Cord*>(message, field),
1867                                  scratch);
1868         } else {
1869           absl::CopyCordToString(GetField<absl::Cord>(message, field), scratch);
1870         }
1871         return *scratch;
1872       case FieldDescriptor::CppStringType::kView:
1873       case FieldDescriptor::CppStringType::kString:
1874         if (IsInlined(field)) {
1875           return GetField<InlinedStringField>(message, field).GetNoArena();
1876         } else {
1877           const auto& str = GetField<ArenaStringPtr>(message, field);
1878           return str.IsDefault() ? internal::DefaultValueStringAsString(field)
1879                                  : str.Get();
1880         }
1881     }
1882     internal::Unreachable();
1883   }
1884 }
1885 
GetCord(const Message & message,const FieldDescriptor * field) const1886 absl::Cord Reflection::GetCord(const Message& message,
1887                                const FieldDescriptor* field) const {
1888   USAGE_CHECK_ALL(GetCord, SINGULAR, STRING);
1889   if (field->is_extension()) {
1890     return absl::Cord(GetExtensionSet(message).GetString(
1891         field->number(), internal::DefaultValueStringAsString(field)));
1892   } else {
1893     if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1894       return absl::Cord(field->default_value_string());
1895     }
1896     switch (field->cpp_string_type()) {
1897       case FieldDescriptor::CppStringType::kCord:
1898         if (schema_.InRealOneof(field)) {
1899           return *GetField<absl::Cord*>(message, field);
1900         } else {
1901           return GetField<absl::Cord>(message, field);
1902         }
1903       case FieldDescriptor::CppStringType::kView:
1904       case FieldDescriptor::CppStringType::kString:
1905         if (IsInlined(field)) {
1906           return absl::Cord(
1907               GetField<InlinedStringField>(message, field).GetNoArena());
1908         } else {
1909           const auto& str = GetField<ArenaStringPtr>(message, field);
1910           return absl::Cord(str.IsDefault() ? field->default_value_string()
1911                                             : str.Get());
1912         }
1913     }
1914     internal::Unreachable();
1915   }
1916 }
1917 
GetStringView(const Message & message,const FieldDescriptor * field,ScratchSpace & scratch) const1918 absl::string_view Reflection::GetStringView(const Message& message,
1919                                             const FieldDescriptor* field,
1920                                             ScratchSpace& scratch) const {
1921   USAGE_CHECK_ALL(GetStringView, SINGULAR, STRING);
1922 
1923   if (field->is_extension()) {
1924     return GetExtensionSet(message).GetString(
1925         field->number(), internal::DefaultValueStringAsString(field));
1926   }
1927   if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
1928     return field->default_value_string();
1929   }
1930 
1931   switch (field->cpp_string_type()) {
1932     case FieldDescriptor::CppStringType::kCord: {
1933       const auto& cord = schema_.InRealOneof(field)
1934                              ? *GetField<absl::Cord*>(message, field)
1935                              : GetField<absl::Cord>(message, field);
1936       return scratch.CopyFromCord(cord);
1937     }
1938     default:
1939       auto str = GetField<ArenaStringPtr>(message, field);
1940       return str.IsDefault() ? field->default_value_string() : str.Get();
1941   }
1942 }
1943 
1944 
SetString(Message * message,const FieldDescriptor * field,std::string value) const1945 void Reflection::SetString(Message* message, const FieldDescriptor* field,
1946                            std::string value) const {
1947   USAGE_MUTABLE_CHECK_ALL(SetString, SINGULAR, STRING);
1948   if (field->is_extension()) {
1949     return MutableExtensionSet(message)->SetString(
1950         field->number(), field->type(), std::move(value), field);
1951   } else {
1952     switch (field->cpp_string_type()) {
1953       case FieldDescriptor::CppStringType::kCord:
1954         if (schema_.InRealOneof(field)) {
1955           if (!HasOneofField(*message, field)) {
1956             ClearOneof(message, field->containing_oneof());
1957             *MutableField<absl::Cord*>(message, field) =
1958                 Arena::Create<absl::Cord>(message->GetArena());
1959           }
1960           *(*MutableField<absl::Cord*>(message, field)) = value;
1961           break;
1962         }
1963         *MutableField<absl::Cord>(message, field) = value;
1964         break;
1965       case FieldDescriptor::CppStringType::kView:
1966       case FieldDescriptor::CppStringType::kString: {
1967         if (IsInlined(field)) {
1968           const uint32_t index = schema_.InlinedStringIndex(field);
1969           ABSL_DCHECK_GT(index, 0u);
1970           uint32_t* states =
1971               &MutableInlinedStringDonatedArray(message)[index / 32];
1972           uint32_t mask = ~(static_cast<uint32_t>(1) << (index % 32));
1973           MutableField<InlinedStringField>(message, field)
1974               ->Set(value, message->GetArena(),
1975                     IsInlinedStringDonated(*message, field), states, mask,
1976                     message);
1977           break;
1978         }
1979 
1980         // Oneof string fields are never set as a default instance.
1981         // We just need to pass some arbitrary default string to make it work.
1982         // This allows us to not have the real default accessible from
1983         // reflection.
1984         if (schema_.InRealOneof(field) && !HasOneofField(*message, field)) {
1985           ClearOneof(message, field->containing_oneof());
1986           MutableField<ArenaStringPtr>(message, field)->InitDefault();
1987         }
1988         MutableField<ArenaStringPtr>(message, field)
1989             ->Set(std::move(value), message->GetArena());
1990         break;
1991       }
1992     }
1993   }
1994 }
1995 
SetString(Message * message,const FieldDescriptor * field,const absl::Cord & value) const1996 void Reflection::SetString(Message* message, const FieldDescriptor* field,
1997                            const absl::Cord& value) const {
1998   USAGE_MUTABLE_CHECK_ALL(SetString, SINGULAR, STRING);
1999   if (field->is_extension()) {
2000     return absl::CopyCordToString(value,
2001                                   MutableExtensionSet(message)->MutableString(
2002                                       field->number(), field->type(), field));
2003   } else {
2004     switch (field->cpp_string_type()) {
2005       case FieldDescriptor::CppStringType::kCord:
2006         if (schema_.InRealOneof(field)) {
2007           if (!HasOneofField(*message, field)) {
2008             ClearOneof(message, field->containing_oneof());
2009             *MutableField<absl::Cord*>(message, field) =
2010                 Arena::Create<absl::Cord>(message->GetArena());
2011           }
2012           *(*MutableField<absl::Cord*>(message, field)) = value;
2013         } else {
2014           *MutableField<absl::Cord>(message, field) = value;
2015         }
2016         break;
2017       case FieldDescriptor::CppStringType::kView:
2018       case FieldDescriptor::CppStringType::kString: {
2019         // Oneof string fields are never set as a default instance.
2020         // We just need to pass some arbitrary default string to make it work.
2021         // This allows us to not have the real default accessible from
2022         // reflection.
2023         if (schema_.InRealOneof(field) && !HasOneofField(*message, field)) {
2024           ClearOneof(message, field->containing_oneof());
2025           MutableField<ArenaStringPtr>(message, field)->InitDefault();
2026         }
2027         if (IsInlined(field)) {
2028           auto* str = MutableField<InlinedStringField>(message, field);
2029           const uint32_t index = schema_.InlinedStringIndex(field);
2030           ABSL_DCHECK_GT(index, 0u);
2031           uint32_t* states =
2032               &MutableInlinedStringDonatedArray(message)[index / 32];
2033           uint32_t mask = ~(static_cast<uint32_t>(1) << (index % 32));
2034           str->Set(std::string(value), message->GetArena(),
2035                    IsInlinedStringDonated(*message, field), states, mask,
2036                    message);
2037         } else {
2038           auto* str = MutableField<ArenaStringPtr>(message, field);
2039           str->Set(std::string(value), message->GetArena());
2040         }
2041         break;
2042       }
2043     }
2044   }
2045 }
2046 
GetRepeatedString(const Message & message,const FieldDescriptor * field,int index) const2047 std::string Reflection::GetRepeatedString(const Message& message,
2048                                           const FieldDescriptor* field,
2049                                           int index) const {
2050   USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
2051   if (field->is_extension()) {
2052     return GetExtensionSet(message).GetRepeatedString(field->number(), index);
2053   } else {
2054     switch (field->cpp_string_type()) {
2055       case FieldDescriptor::CppStringType::kCord:
2056         return std::string(GetRepeatedField<absl::Cord>(message, field, index));
2057       case FieldDescriptor::CppStringType::kView:
2058       case FieldDescriptor::CppStringType::kString:
2059         return GetRepeatedPtrField<std::string>(message, field, index);
2060     }
2061     internal::Unreachable();
2062   }
2063 }
2064 
GetRepeatedStringReference(const Message & message,const FieldDescriptor * field,int index,std::string * scratch) const2065 const std::string& Reflection::GetRepeatedStringReference(
2066     const Message& message, const FieldDescriptor* field, int index,
2067     std::string* scratch) const {
2068   (void)scratch;  // Parameter is used by Google-internal code.
2069   USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
2070   if (field->is_extension()) {
2071     return GetExtensionSet(message).GetRepeatedString(field->number(), index);
2072   } else {
2073     switch (field->cpp_string_type()) {
2074       case FieldDescriptor::CppStringType::kCord:
2075         absl::CopyCordToString(
2076             GetRepeatedField<absl::Cord>(message, field, index), scratch);
2077         return *scratch;
2078       case FieldDescriptor::CppStringType::kView:
2079       case FieldDescriptor::CppStringType::kString:
2080         return GetRepeatedPtrField<std::string>(message, field, index);
2081     }
2082     internal::Unreachable();
2083   }
2084 }
2085 
2086 // See GetStringView(), above.
GetRepeatedStringView(const Message & message,const FieldDescriptor * field,int index,ScratchSpace & scratch) const2087 absl::string_view Reflection::GetRepeatedStringView(
2088     const Message& message, const FieldDescriptor* field, int index,
2089     ScratchSpace& scratch) const {
2090   (void)scratch;
2091   USAGE_CHECK_ALL(GetRepeatedStringView, REPEATED, STRING);
2092 
2093   if (field->is_extension()) {
2094     return GetExtensionSet(message).GetRepeatedString(field->number(), index);
2095   }
2096 
2097   switch (field->cpp_string_type()) {
2098     case FieldDescriptor::CppStringType::kCord: {
2099       auto& cord = GetRepeatedField<absl::Cord>(message, field, index);
2100       return scratch.CopyFromCord(cord);
2101     }
2102     case FieldDescriptor::CppStringType::kView:
2103     case FieldDescriptor::CppStringType::kString:
2104       return GetRepeatedPtrField<std::string>(message, field, index);
2105   }
2106   internal::Unreachable();
2107 }
2108 
2109 
SetRepeatedString(Message * message,const FieldDescriptor * field,int index,std::string value) const2110 void Reflection::SetRepeatedString(Message* message,
2111                                    const FieldDescriptor* field, int index,
2112                                    std::string value) const {
2113   USAGE_MUTABLE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
2114   if (field->is_extension()) {
2115     MutableExtensionSet(message)->SetRepeatedString(field->number(), index,
2116                                                     std::move(value));
2117   } else {
2118     switch (field->cpp_string_type()) {
2119       case FieldDescriptor::CppStringType::kCord:
2120         SetRepeatedField<absl::Cord>(message, field, index, absl::Cord(value));
2121         break;
2122       case FieldDescriptor::CppStringType::kView:
2123       case FieldDescriptor::CppStringType::kString:
2124         MutableRepeatedField<std::string>(message, field, index)
2125             ->assign(std::move(value));
2126         break;
2127     }
2128   }
2129 }
2130 
2131 
AddString(Message * message,const FieldDescriptor * field,std::string value) const2132 void Reflection::AddString(Message* message, const FieldDescriptor* field,
2133                            std::string value) const {
2134   USAGE_MUTABLE_CHECK_ALL(AddString, REPEATED, STRING);
2135   if (field->is_extension()) {
2136     MutableExtensionSet(message)->AddString(field->number(), field->type(),
2137                                             std::move(value), field);
2138   } else {
2139     switch (field->cpp_string_type()) {
2140       case FieldDescriptor::CppStringType::kCord:
2141         AddField<absl::Cord>(message, field, absl::Cord(value));
2142         break;
2143       case FieldDescriptor::CppStringType::kView:
2144       case FieldDescriptor::CppStringType::kString:
2145         AddField<std::string>(message, field)->assign(std::move(value));
2146         break;
2147     }
2148   }
2149 }
2150 
2151 
2152 // -------------------------------------------------------------------
2153 
GetEnum(const Message & message,const FieldDescriptor * field) const2154 const EnumValueDescriptor* Reflection::GetEnum(
2155     const Message& message, const FieldDescriptor* field) const {
2156   // Usage checked by GetEnumValue.
2157   int value = GetEnumValue(message, field);
2158   return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
2159 }
2160 
GetEnumValue(const Message & message,const FieldDescriptor * field) const2161 int Reflection::GetEnumValue(const Message& message,
2162                              const FieldDescriptor* field) const {
2163   USAGE_CHECK_ALL(GetEnumValue, SINGULAR, ENUM);
2164 
2165   int32_t value;
2166   if (field->is_extension()) {
2167     value = GetExtensionSet(message).GetEnum(
2168         field->number(), field->default_value_enum()->number());
2169   } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
2170     value = field->default_value_enum()->number();
2171   } else {
2172     value = GetField<int>(message, field);
2173   }
2174   return value;
2175 }
2176 
SetEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const2177 void Reflection::SetEnum(Message* message, const FieldDescriptor* field,
2178                          const EnumValueDescriptor* value) const {
2179   // Usage checked by SetEnumValue.
2180   USAGE_CHECK_ENUM_VALUE(SetEnum);
2181   SetEnumValueInternal(message, field, value->number());
2182 }
2183 
SetEnumValue(Message * message,const FieldDescriptor * field,int value) const2184 void Reflection::SetEnumValue(Message* message, const FieldDescriptor* field,
2185                               int value) const {
2186   USAGE_MUTABLE_CHECK_ALL(SetEnumValue, SINGULAR, ENUM);
2187   if (!CreateUnknownEnumValues(field)) {
2188     // Check that the value is valid if we don't support direct storage of
2189     // unknown enum values.
2190     const EnumValueDescriptor* value_desc =
2191         field->enum_type()->FindValueByNumber(value);
2192     if (value_desc == nullptr) {
2193       MutableUnknownFields(message)->AddVarint(field->number(), value);
2194       return;
2195     }
2196   }
2197   SetEnumValueInternal(message, field, value);
2198 }
2199 
SetEnumValueInternal(Message * message,const FieldDescriptor * field,int value) const2200 void Reflection::SetEnumValueInternal(Message* message,
2201                                       const FieldDescriptor* field,
2202                                       int value) const {
2203   if (field->is_extension()) {
2204     MutableExtensionSet(message)->SetEnum(field->number(), field->type(), value,
2205                                           field);
2206   } else {
2207     SetField<int>(message, field, value);
2208   }
2209 }
2210 
GetRepeatedEnum(const Message & message,const FieldDescriptor * field,int index) const2211 const EnumValueDescriptor* Reflection::GetRepeatedEnum(
2212     const Message& message, const FieldDescriptor* field, int index) const {
2213   // Usage checked by GetRepeatedEnumValue.
2214   int value = GetRepeatedEnumValue(message, field, index);
2215   return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
2216 }
2217 
GetRepeatedEnumValue(const Message & message,const FieldDescriptor * field,int index) const2218 int Reflection::GetRepeatedEnumValue(const Message& message,
2219                                      const FieldDescriptor* field,
2220                                      int index) const {
2221   USAGE_CHECK_ALL(GetRepeatedEnumValue, REPEATED, ENUM);
2222 
2223   int value;
2224   if (field->is_extension()) {
2225     value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
2226   } else {
2227     value = GetRepeatedField<int>(message, field, index);
2228   }
2229   return value;
2230 }
2231 
SetRepeatedEnum(Message * message,const FieldDescriptor * field,int index,const EnumValueDescriptor * value) const2232 void Reflection::SetRepeatedEnum(Message* message, const FieldDescriptor* field,
2233                                  int index,
2234                                  const EnumValueDescriptor* value) const {
2235   // Usage checked by SetRepeatedEnumValue.
2236   USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
2237   SetRepeatedEnumValueInternal(message, field, index, value->number());
2238 }
2239 
SetRepeatedEnumValue(Message * message,const FieldDescriptor * field,int index,int value) const2240 void Reflection::SetRepeatedEnumValue(Message* message,
2241                                       const FieldDescriptor* field, int index,
2242                                       int value) const {
2243   USAGE_MUTABLE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
2244   if (!CreateUnknownEnumValues(field)) {
2245     // Check that the value is valid if we don't support direct storage of
2246     // unknown enum values.
2247     const EnumValueDescriptor* value_desc =
2248         field->enum_type()->FindValueByNumber(value);
2249     if (value_desc == nullptr) {
2250       MutableUnknownFields(message)->AddVarint(field->number(), value);
2251       return;
2252     }
2253   }
2254   SetRepeatedEnumValueInternal(message, field, index, value);
2255 }
2256 
SetRepeatedEnumValueInternal(Message * message,const FieldDescriptor * field,int index,int value) const2257 void Reflection::SetRepeatedEnumValueInternal(Message* message,
2258                                               const FieldDescriptor* field,
2259                                               int index, int value) const {
2260   if (field->is_extension()) {
2261     MutableExtensionSet(message)->SetRepeatedEnum(field->number(), index,
2262                                                   value);
2263   } else {
2264     SetRepeatedField<int>(message, field, index, value);
2265   }
2266 }
2267 
AddEnum(Message * message,const FieldDescriptor * field,const EnumValueDescriptor * value) const2268 void Reflection::AddEnum(Message* message, const FieldDescriptor* field,
2269                          const EnumValueDescriptor* value) const {
2270   // Usage checked by AddEnumValue.
2271   USAGE_CHECK_ENUM_VALUE(AddEnum);
2272   AddEnumValueInternal(message, field, value->number());
2273 }
2274 
AddEnumValue(Message * message,const FieldDescriptor * field,int value) const2275 void Reflection::AddEnumValue(Message* message, const FieldDescriptor* field,
2276                               int value) const {
2277   USAGE_MUTABLE_CHECK_ALL(AddEnum, REPEATED, ENUM);
2278   if (!CreateUnknownEnumValues(field)) {
2279     // Check that the value is valid if we don't support direct storage of
2280     // unknown enum values.
2281     const EnumValueDescriptor* value_desc =
2282         field->enum_type()->FindValueByNumber(value);
2283     if (value_desc == nullptr) {
2284       MutableUnknownFields(message)->AddVarint(field->number(), value);
2285       return;
2286     }
2287   }
2288   AddEnumValueInternal(message, field, value);
2289 }
2290 
AddEnumValueInternal(Message * message,const FieldDescriptor * field,int value) const2291 void Reflection::AddEnumValueInternal(Message* message,
2292                                       const FieldDescriptor* field,
2293                                       int value) const {
2294   if (field->is_extension()) {
2295     MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
2296                                           field->is_packed(), value, field);
2297   } else {
2298     AddField<int>(message, field, value);
2299   }
2300 }
2301 
2302 // -------------------------------------------------------------------
2303 
GetDefaultMessageInstance(const FieldDescriptor * field) const2304 const Message* Reflection::GetDefaultMessageInstance(
2305     const FieldDescriptor* field) const {
2306   // If we are using the generated factory, we cache the prototype in the field
2307   // descriptor for faster access.
2308   // The default instances of generated messages are not cross-linked, which
2309   // means they contain null pointers on their message fields and can't be used
2310   // to get the default of submessages.
2311   if (message_factory_ == MessageFactory::generated_factory()) {
2312     auto& ptr = field->default_generated_instance_;
2313     auto* res = ptr.load(std::memory_order_acquire);
2314     if (res == nullptr) {
2315       // First time asking for this field's default. Load it and cache it.
2316       res = message_factory_->GetPrototype(field->message_type());
2317       ptr.store(res, std::memory_order_release);
2318     }
2319     return res;
2320   }
2321 
2322   // For other factories, we try the default's object field.
2323   // In particular, the DynamicMessageFactory will cross link the default
2324   // instances to allow for this. But only do this for real fields.
2325   // This is an optimization to avoid going to GetPrototype() below, as that
2326   // requires a lock and a map lookup.
2327   if (!field->is_extension() && !field->options().weak() &&
2328       !IsLazyField(field) && !schema_.InRealOneof(field)) {
2329     auto* res = DefaultRaw<const Message*>(field);
2330     if (res != nullptr) {
2331       return res;
2332     }
2333   }
2334   // Otherwise, just go to the factory.
2335   return message_factory_->GetPrototype(field->message_type());
2336 }
2337 
GetMessage(const Message & message,const FieldDescriptor * field,MessageFactory * factory) const2338 const Message& Reflection::GetMessage(const Message& message,
2339                                       const FieldDescriptor* field,
2340                                       MessageFactory* factory) const {
2341   USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
2342 
2343   if (factory == nullptr) factory = message_factory_;
2344 
2345   if (field->is_extension()) {
2346     return static_cast<const Message&>(GetExtensionSet(message).GetMessage(
2347         field->number(), field->message_type(), factory));
2348   } else {
2349     if (schema_.InRealOneof(field) && !HasOneofField(message, field)) {
2350       return *GetDefaultMessageInstance(field);
2351     }
2352     const Message* result = GetRaw<const Message*>(message, field);
2353     if (result == nullptr) {
2354       result = GetDefaultMessageInstance(field);
2355     }
2356     return *result;
2357   }
2358 }
2359 
MutableMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const2360 Message* Reflection::MutableMessage(Message* message,
2361                                     const FieldDescriptor* field,
2362                                     MessageFactory* factory) const {
2363   USAGE_MUTABLE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
2364 
2365   if (factory == nullptr) factory = message_factory_;
2366 
2367   if (field->is_extension()) {
2368     return static_cast<Message*>(
2369         MutableExtensionSet(message)->MutableMessage(field, factory));
2370   } else {
2371     Message* result;
2372 
2373     Message** result_holder = MutableRaw<Message*>(message, field);
2374 
2375     if (schema_.InRealOneof(field)) {
2376       if (!HasOneofField(*message, field)) {
2377         ClearOneof(message, field->containing_oneof());
2378         result_holder = MutableField<Message*>(message, field);
2379         const Message* default_message = GetDefaultMessageInstance(field);
2380         *result_holder = default_message->New(message->GetArena());
2381       }
2382     } else {
2383       SetHasBit(message, field);
2384     }
2385 
2386     if (*result_holder == nullptr) {
2387       const Message* default_message = GetDefaultMessageInstance(field);
2388       *result_holder = default_message->New(message->GetArena());
2389     }
2390     result = *result_holder;
2391     return result;
2392   }
2393 }
2394 
UnsafeArenaSetAllocatedMessage(Message * message,Message * sub_message,const FieldDescriptor * field) const2395 void Reflection::UnsafeArenaSetAllocatedMessage(
2396     Message* message, Message* sub_message,
2397     const FieldDescriptor* field) const {
2398   USAGE_MUTABLE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
2399 
2400 
2401   if (field->is_extension()) {
2402     MutableExtensionSet(message)->UnsafeArenaSetAllocatedMessage(
2403         field->number(), field->type(), field, sub_message);
2404   } else {
2405     if (schema_.InRealOneof(field)) {
2406       if (sub_message == nullptr) {
2407         ClearOneof(message, field->containing_oneof());
2408         return;
2409       }
2410         ClearOneof(message, field->containing_oneof());
2411         *MutableRaw<Message*>(message, field) = sub_message;
2412       SetOneofCase(message, field);
2413       return;
2414     }
2415 
2416     if (sub_message == nullptr) {
2417       ClearHasBit(message, field);
2418     } else {
2419       SetHasBit(message, field);
2420     }
2421     Message** sub_message_holder = MutableRaw<Message*>(message, field);
2422     if (message->GetArena() == nullptr) {
2423       delete *sub_message_holder;
2424     }
2425     *sub_message_holder = sub_message;
2426   }
2427 }
2428 
SetAllocatedMessage(Message * message,Message * sub_message,const FieldDescriptor * field) const2429 void Reflection::SetAllocatedMessage(Message* message, Message* sub_message,
2430                                      const FieldDescriptor* field) const {
2431   ABSL_DCHECK(sub_message == nullptr || sub_message->GetArena() == nullptr ||
2432               sub_message->GetArena() == message->GetArena());
2433 
2434   if (sub_message == nullptr) {
2435     UnsafeArenaSetAllocatedMessage(message, nullptr, field);
2436     return;
2437   }
2438 
2439   Arena* arena = message->GetArena();
2440   Arena* sub_arena = sub_message->GetArena();
2441   if (arena == sub_arena) {
2442     UnsafeArenaSetAllocatedMessage(message, sub_message, field);
2443     return;
2444   }
2445 
2446   // If message and sub-message are in different memory ownership domains
2447   // (different arenas, or one is on heap and one is not), then we may need to
2448   // do a copy.
2449   if (sub_arena == nullptr) {
2450     ABSL_DCHECK_NE(arena, nullptr);
2451     // Case 1: parent is on an arena and child is heap-allocated. We can add
2452     // the child to the arena's Own() list to free on arena destruction, then
2453     // set our pointer.
2454     arena->Own(sub_message);
2455     UnsafeArenaSetAllocatedMessage(message, sub_message, field);
2456   } else {
2457     // Case 2: all other cases. We need to make a copy. MutableMessage() will
2458     // either get the existing message object, or instantiate a new one as
2459     // appropriate w.r.t. our arena.
2460     Message* sub_message_copy = MutableMessage(message, field);
2461     sub_message_copy->CopyFrom(*sub_message);
2462   }
2463 }
2464 
UnsafeArenaReleaseMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const2465 Message* Reflection::UnsafeArenaReleaseMessage(Message* message,
2466                                                const FieldDescriptor* field,
2467                                                MessageFactory* factory) const {
2468   USAGE_MUTABLE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
2469 
2470   if (factory == nullptr) factory = message_factory_;
2471 
2472   if (field->is_extension()) {
2473     return static_cast<Message*>(
2474         MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field,
2475                                                                 factory));
2476   } else {
2477     if (!(field->is_repeated() || schema_.InRealOneof(field))) {
2478       ClearHasBit(message, field);
2479     }
2480     if (schema_.InRealOneof(field)) {
2481       if (HasOneofField(*message, field)) {
2482         *MutableOneofCase(message, field->containing_oneof()) = 0;
2483       } else {
2484         return nullptr;
2485       }
2486     }
2487     Message** result = MutableRaw<Message*>(message, field);
2488     Message* ret = *result;
2489     *result = nullptr;
2490     return ret;
2491   }
2492 }
2493 
ReleaseMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const2494 Message* Reflection::ReleaseMessage(Message* message,
2495                                     const FieldDescriptor* field,
2496                                     MessageFactory* factory) const {
2497   Message* released = UnsafeArenaReleaseMessage(message, field, factory);
2498   if (internal::DebugHardenForceCopyInRelease()) {
2499     released = MaybeForceCopy(message->GetArena(), released);
2500   }
2501   if (message->GetArena() != nullptr && released != nullptr) {
2502     Message* copy_from_arena = released->New();
2503     copy_from_arena->CopyFrom(*released);
2504     released = copy_from_arena;
2505   }
2506   return released;
2507 }
2508 
GetRepeatedMessage(const Message & message,const FieldDescriptor * field,int index) const2509 const Message& Reflection::GetRepeatedMessage(const Message& message,
2510                                               const FieldDescriptor* field,
2511                                               int index) const {
2512   USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
2513 
2514   if (field->is_extension()) {
2515     return static_cast<const Message&>(
2516         GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
2517   } else {
2518     if (IsMapFieldInApi(field)) {
2519       return GetRaw<MapFieldBase>(message, field)
2520           .GetRepeatedField()
2521           .Get<GenericTypeHandler<Message> >(index);
2522     } else {
2523       return GetRaw<RepeatedPtrFieldBase>(message, field)
2524           .Get<GenericTypeHandler<Message> >(index);
2525     }
2526   }
2527 }
2528 
MutableRepeatedMessage(Message * message,const FieldDescriptor * field,int index) const2529 Message* Reflection::MutableRepeatedMessage(Message* message,
2530                                             const FieldDescriptor* field,
2531                                             int index) const {
2532   USAGE_MUTABLE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
2533 
2534   if (field->is_extension()) {
2535     return static_cast<Message*>(
2536         MutableExtensionSet(message)->MutableRepeatedMessage(field->number(),
2537                                                              index));
2538   } else {
2539     if (IsMapFieldInApi(field)) {
2540       return MutableRaw<MapFieldBase>(message, field)
2541           ->MutableRepeatedField()
2542           ->Mutable<GenericTypeHandler<Message> >(index);
2543     } else {
2544       return MutableRaw<RepeatedPtrFieldBase>(message, field)
2545           ->Mutable<GenericTypeHandler<Message> >(index);
2546     }
2547   }
2548 }
2549 
AddMessage(Message * message,const FieldDescriptor * field,MessageFactory * factory) const2550 Message* Reflection::AddMessage(Message* message, const FieldDescriptor* field,
2551                                 MessageFactory* factory) const {
2552   USAGE_MUTABLE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
2553 
2554   if (factory == nullptr) factory = message_factory_;
2555 
2556   if (field->is_extension()) {
2557     return static_cast<Message*>(
2558         MutableExtensionSet(message)->AddMessage(field, factory));
2559   } else {
2560     Message* result = nullptr;
2561 
2562     // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
2563     // know how to allocate one.
2564     RepeatedPtrFieldBase* repeated = nullptr;
2565     if (IsMapFieldInApi(field)) {
2566       repeated =
2567           MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
2568     } else {
2569       repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
2570     }
2571     result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
2572     if (result == nullptr) {
2573       // We must allocate a new object.
2574       const Message* prototype;
2575       if (repeated->size() == 0) {
2576         prototype = factory->GetPrototype(field->message_type());
2577       } else {
2578         prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
2579       }
2580       result = prototype->New(message->GetArena());
2581       // We can guarantee here that repeated and result are either both heap
2582       // allocated or arena owned. So it is safe to call the unsafe version
2583       // of AddAllocated.
2584       repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message> >(result);
2585     }
2586 
2587     return result;
2588   }
2589 }
2590 
AddAllocatedMessage(Message * message,const FieldDescriptor * field,Message * new_entry) const2591 void Reflection::AddAllocatedMessage(Message* message,
2592                                      const FieldDescriptor* field,
2593                                      Message* new_entry) const {
2594   USAGE_MUTABLE_CHECK_ALL(AddAllocatedMessage, REPEATED, MESSAGE);
2595 
2596   if (field->is_extension()) {
2597     MutableExtensionSet(message)->AddAllocatedMessage(field, new_entry);
2598   } else {
2599     RepeatedPtrFieldBase* repeated = nullptr;
2600     if (IsMapFieldInApi(field)) {
2601       repeated =
2602           MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
2603     } else {
2604       repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
2605     }
2606     repeated->AddAllocated<GenericTypeHandler<Message> >(new_entry);
2607   }
2608 }
2609 
UnsafeArenaAddAllocatedMessage(Message * message,const FieldDescriptor * field,Message * new_entry) const2610 void Reflection::UnsafeArenaAddAllocatedMessage(Message* message,
2611                                                 const FieldDescriptor* field,
2612                                                 Message* new_entry) const {
2613   USAGE_MUTABLE_CHECK_ALL(UnsafeArenaAddAllocatedMessage, REPEATED, MESSAGE);
2614 
2615   if (field->is_extension()) {
2616     MutableExtensionSet(message)->UnsafeArenaAddAllocatedMessage(field,
2617                                                                  new_entry);
2618   } else {
2619     RepeatedPtrFieldBase* repeated = nullptr;
2620     if (IsMapFieldInApi(field)) {
2621       repeated =
2622           MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
2623     } else {
2624       repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
2625     }
2626     repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message>>(new_entry);
2627   }
2628 }
2629 
MutableRawRepeatedField(Message * message,const FieldDescriptor * field,FieldDescriptor::CppType cpptype,int ctype,const Descriptor * desc) const2630 void* Reflection::MutableRawRepeatedField(Message* message,
2631                                           const FieldDescriptor* field,
2632                                           FieldDescriptor::CppType cpptype,
2633                                           int ctype,
2634                                           const Descriptor* desc) const {
2635   (void)ctype;  // Parameter is used by Google-internal code.
2636   USAGE_CHECK_REPEATED("MutableRawRepeatedField");
2637   USAGE_CHECK_MESSAGE_TYPE(MutableRawRepeatedField);
2638 
2639   if (field->cpp_type() != cpptype &&
2640       (field->cpp_type() != FieldDescriptor::CPPTYPE_ENUM ||
2641        cpptype != FieldDescriptor::CPPTYPE_INT32))
2642     ReportReflectionUsageTypeError(descriptor_, field,
2643                                    "MutableRawRepeatedField", cpptype);
2644   if (desc != nullptr)
2645     ABSL_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
2646   if (field->is_extension()) {
2647     return MutableExtensionSet(message)->MutableRawRepeatedField(
2648         field->number(), field->type(), field->is_packed(), field);
2649   } else {
2650     // Trigger transform for MapField
2651     if (IsMapFieldInApi(field)) {
2652       return MutableRawNonOneof<MapFieldBase>(message, field)
2653           ->MutableRepeatedField();
2654     }
2655     return MutableRawNonOneof<void>(message, field);
2656   }
2657 }
2658 
GetRawRepeatedField(const Message & message,const FieldDescriptor * field,FieldDescriptor::CppType cpptype,int ctype,const Descriptor * desc) const2659 const void* Reflection::GetRawRepeatedField(const Message& message,
2660                                             const FieldDescriptor* field,
2661                                             FieldDescriptor::CppType cpptype,
2662                                             int ctype,
2663                                             const Descriptor* desc) const {
2664   USAGE_CHECK_REPEATED("GetRawRepeatedField");
2665   USAGE_CHECK_MESSAGE_TYPE(GetRawRepeatedField);
2666   if (field->cpp_type() != cpptype &&
2667       (field->cpp_type() != FieldDescriptor::CPPTYPE_ENUM ||
2668        cpptype != FieldDescriptor::CPPTYPE_INT32))
2669     ReportReflectionUsageTypeError(descriptor_, field, "GetRawRepeatedField",
2670                                    cpptype);
2671   if (ctype >= 0)
2672     ABSL_CHECK_EQ(internal::cpp::EffectiveStringCType(field), ctype)
2673         << "subtype mismatch";
2674   if (desc != nullptr)
2675     ABSL_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
2676   if (field->is_extension()) {
2677     return GetExtensionSet(message).GetRawRepeatedField(
2678         field->number(), internal::DefaultRawPtr());
2679   } else {
2680     // Trigger transform for MapField
2681     if (IsMapFieldInApi(field)) {
2682       return &(GetRawNonOneof<MapFieldBase>(message, field).GetRepeatedField());
2683     }
2684     return &GetRawNonOneof<char>(message, field);
2685   }
2686 }
2687 
GetOneofFieldDescriptor(const Message & message,const OneofDescriptor * oneof_descriptor) const2688 const FieldDescriptor* Reflection::GetOneofFieldDescriptor(
2689     const Message& message, const OneofDescriptor* oneof_descriptor) const {
2690   if (oneof_descriptor->is_synthetic()) {
2691     const FieldDescriptor* field = oneof_descriptor->field(0);
2692     return HasField(message, field) ? field : nullptr;
2693   }
2694   uint32_t field_number = GetOneofCase(message, oneof_descriptor);
2695   if (field_number == 0) {
2696     return nullptr;
2697   }
2698   return descriptor_->FindFieldByNumber(field_number);
2699 }
2700 
ContainsMapKey(const Message & message,const FieldDescriptor * field,const MapKey & key) const2701 bool Reflection::ContainsMapKey(const Message& message,
2702                                 const FieldDescriptor* field,
2703                                 const MapKey& key) const {
2704   USAGE_CHECK(IsMapFieldInApi(field), LookupMapValue,
2705               "Field is not a map field.");
2706   return GetRaw<MapFieldBase>(message, field).ContainsMapKey(key);
2707 }
2708 
InsertOrLookupMapValue(Message * message,const FieldDescriptor * field,const MapKey & key,MapValueRef * val) const2709 bool Reflection::InsertOrLookupMapValue(Message* message,
2710                                         const FieldDescriptor* field,
2711                                         const MapKey& key,
2712                                         MapValueRef* val) const {
2713   USAGE_CHECK(IsMapFieldInApi(field), InsertOrLookupMapValue,
2714               "Field is not a map field.");
2715   val->SetType(field->message_type()->map_value()->cpp_type());
2716   return MutableRaw<MapFieldBase>(message, field)
2717       ->InsertOrLookupMapValue(key, val);
2718 }
2719 
LookupMapValue(const Message & message,const FieldDescriptor * field,const MapKey & key,MapValueConstRef * val) const2720 bool Reflection::LookupMapValue(const Message& message,
2721                                 const FieldDescriptor* field, const MapKey& key,
2722                                 MapValueConstRef* val) const {
2723   USAGE_CHECK(IsMapFieldInApi(field), LookupMapValue,
2724               "Field is not a map field.");
2725   val->SetType(field->message_type()->map_value()->cpp_type());
2726   return GetRaw<MapFieldBase>(message, field).LookupMapValue(key, val);
2727 }
2728 
DeleteMapValue(Message * message,const FieldDescriptor * field,const MapKey & key) const2729 bool Reflection::DeleteMapValue(Message* message, const FieldDescriptor* field,
2730                                 const MapKey& key) const {
2731   USAGE_CHECK(IsMapFieldInApi(field), DeleteMapValue,
2732               "Field is not a map field.");
2733   return MutableRaw<MapFieldBase>(message, field)->DeleteMapValue(key);
2734 }
2735 
MapBegin(Message * message,const FieldDescriptor * field) const2736 MapIterator Reflection::MapBegin(Message* message,
2737                                  const FieldDescriptor* field) const {
2738   USAGE_CHECK(IsMapFieldInApi(field), MapBegin, "Field is not a map field.");
2739   MapIterator iter(message, field);
2740   GetRaw<MapFieldBase>(*message, field).MapBegin(&iter);
2741   return iter;
2742 }
2743 
MapEnd(Message * message,const FieldDescriptor * field) const2744 MapIterator Reflection::MapEnd(Message* message,
2745                                const FieldDescriptor* field) const {
2746   USAGE_CHECK(IsMapFieldInApi(field), MapEnd, "Field is not a map field.");
2747   MapIterator iter(message, field);
2748   GetRaw<MapFieldBase>(*message, field).MapEnd(&iter);
2749   return iter;
2750 }
2751 
MapSize(const Message & message,const FieldDescriptor * field) const2752 int Reflection::MapSize(const Message& message,
2753                         const FieldDescriptor* field) const {
2754   USAGE_CHECK(IsMapFieldInApi(field), MapSize, "Field is not a map field.");
2755   return GetRaw<MapFieldBase>(message, field).size();
2756 }
2757 
2758 // -----------------------------------------------------------------------------
2759 
FindKnownExtensionByName(absl::string_view name) const2760 const FieldDescriptor* Reflection::FindKnownExtensionByName(
2761     absl::string_view name) const {
2762   if (!schema_.HasExtensionSet()) return nullptr;
2763   return descriptor_pool_->FindExtensionByPrintableName(descriptor_, name);
2764 }
2765 
FindKnownExtensionByNumber(int number) const2766 const FieldDescriptor* Reflection::FindKnownExtensionByNumber(
2767     int number) const {
2768   if (!schema_.HasExtensionSet()) return nullptr;
2769   return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
2770 }
2771 
2772 // ===================================================================
2773 // Some private helpers.
2774 
2775 // These simple template accessors obtain pointers (or references) to
2776 // the given field.
2777 
PrepareSplitMessageForWrite(Message * message) const2778 void Reflection::PrepareSplitMessageForWrite(Message* message) const {
2779   ABSL_DCHECK_NE(message, schema_.default_instance_);
2780   void** split = MutableSplitField(message);
2781   const void* default_split = GetSplitField(schema_.default_instance_);
2782   if (*split == default_split) {
2783     uint32_t size = schema_.SizeofSplit();
2784     Arena* arena = message->GetArena();
2785     *split = (arena == nullptr) ? ::operator new(size)
2786                                 : arena->AllocateAligned(size);
2787     memcpy(*split, default_split, size);
2788   }
2789 }
2790 
2791 template <class Type>
AllocIfDefault(const FieldDescriptor * field,Type * & ptr,Arena * arena)2792 static Type* AllocIfDefault(const FieldDescriptor* field, Type*& ptr,
2793                             Arena* arena) {
2794   if (ptr == internal::DefaultRawPtr()) {
2795     // Note: we can't rely on Type to distinguish between these cases (Type can
2796     // be e.g. char).
2797     if (field->cpp_type() < FieldDescriptor::CPPTYPE_STRING ||
2798         (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
2799          field->cpp_string_type() == FieldDescriptor::CppStringType::kCord)) {
2800       ptr =
2801           reinterpret_cast<Type*>(Arena::Create<RepeatedField<int32_t>>(arena));
2802     } else {
2803       ptr = reinterpret_cast<Type*>(Arena::Create<RepeatedPtrFieldBase>(arena));
2804     }
2805   }
2806   return ptr;
2807 }
2808 
MutableRawSplitImpl(Message * message,const FieldDescriptor * field) const2809 void* Reflection::MutableRawSplitImpl(Message* message,
2810                                       const FieldDescriptor* field) const {
2811   ABSL_DCHECK(!schema_.InRealOneof(field)) << "Field = " << field->full_name();
2812 
2813   const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field);
2814   PrepareSplitMessageForWrite(message);
2815   void** split = MutableSplitField(message);
2816   if (SplitFieldHasExtraIndirection(field)) {
2817     return AllocIfDefault(field,
2818                           *GetPointerAtOffset<void*>(*split, field_offset),
2819                           message->GetArena());
2820   }
2821   return GetPointerAtOffset<void>(*split, field_offset);
2822 }
2823 
MutableRawNonOneofImpl(Message * message,const FieldDescriptor * field) const2824 void* Reflection::MutableRawNonOneofImpl(Message* message,
2825                                          const FieldDescriptor* field) const {
2826   if (PROTOBUF_PREDICT_FALSE(schema_.IsSplit(field))) {
2827     return MutableRawSplitImpl(message, field);
2828   }
2829 
2830   const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field);
2831   return GetPointerAtOffset<void>(message, field_offset);
2832 }
2833 
MutableRawImpl(Message * message,const FieldDescriptor * field) const2834 void* Reflection::MutableRawImpl(Message* message,
2835                                  const FieldDescriptor* field) const {
2836   if (PROTOBUF_PREDICT_TRUE(!schema_.InRealOneof(field))) {
2837     return MutableRawNonOneofImpl(message, field);
2838   }
2839 
2840   // Oneof fields are not split.
2841   ABSL_DCHECK(!schema_.IsSplit(field));
2842 
2843   const uint32_t field_offset = schema_.GetFieldOffset(field);
2844   return GetPointerAtOffset<void>(message, field_offset);
2845 }
2846 
GetHasBits(const Message & message) const2847 const uint32_t* Reflection::GetHasBits(const Message& message) const {
2848   ABSL_DCHECK(schema_.HasHasbits());
2849   return &GetConstRefAtOffset<uint32_t>(message, schema_.HasBitsOffset());
2850 }
2851 
MutableHasBits(Message * message) const2852 uint32_t* Reflection::MutableHasBits(Message* message) const {
2853   ABSL_DCHECK(schema_.HasHasbits());
2854   return GetPointerAtOffset<uint32_t>(message, schema_.HasBitsOffset());
2855 }
2856 
GetOneofCase(const Message & message,const OneofDescriptor * oneof_descriptor) const2857 uint32_t Reflection::GetOneofCase(
2858     const Message& message, const OneofDescriptor* oneof_descriptor) const {
2859   ABSL_DCHECK(!oneof_descriptor->is_synthetic());
2860   return internal::GetConstRefAtOffset<uint32_t>(
2861       message, schema_.GetOneofCaseOffset(oneof_descriptor));
2862 }
2863 
MutableOneofCase(Message * message,const OneofDescriptor * oneof_descriptor) const2864 uint32_t* Reflection::MutableOneofCase(
2865     Message* message, const OneofDescriptor* oneof_descriptor) const {
2866   ABSL_DCHECK(!oneof_descriptor->is_synthetic());
2867   return GetPointerAtOffset<uint32_t>(
2868       message, schema_.GetOneofCaseOffset(oneof_descriptor));
2869 }
2870 
GetExtensionSet(const Message & message) const2871 const ExtensionSet& Reflection::GetExtensionSet(const Message& message) const {
2872   return GetConstRefAtOffset<ExtensionSet>(message,
2873                                            schema_.GetExtensionSetOffset());
2874 }
2875 
MutableExtensionSet(Message * message) const2876 ExtensionSet* Reflection::MutableExtensionSet(Message* message) const {
2877   return GetPointerAtOffset<ExtensionSet>(message,
2878                                           schema_.GetExtensionSetOffset());
2879 }
2880 
GetInternalMetadata(const Message & message) const2881 const InternalMetadata& Reflection::GetInternalMetadata(
2882     const Message& message) const {
2883   return GetConstRefAtOffset<InternalMetadata>(message,
2884                                                schema_.GetMetadataOffset());
2885 }
2886 
MutableInternalMetadata(Message * message) const2887 InternalMetadata* Reflection::MutableInternalMetadata(Message* message) const {
2888   return GetPointerAtOffset<InternalMetadata>(message,
2889                                               schema_.GetMetadataOffset());
2890 }
2891 
GetInlinedStringDonatedArray(const Message & message) const2892 const uint32_t* Reflection::GetInlinedStringDonatedArray(
2893     const Message& message) const {
2894   ABSL_DCHECK(schema_.HasInlinedString());
2895   return &GetConstRefAtOffset<uint32_t>(message,
2896                                         schema_.InlinedStringDonatedOffset());
2897 }
2898 
MutableInlinedStringDonatedArray(Message * message) const2899 uint32_t* Reflection::MutableInlinedStringDonatedArray(Message* message) const {
2900   ABSL_DCHECK(schema_.HasInlinedString());
2901   return GetPointerAtOffset<uint32_t>(message,
2902                                       schema_.InlinedStringDonatedOffset());
2903 }
2904 
2905 // Simple accessors for manipulating _inlined_string_donated_;
IsInlinedStringDonated(const Message & message,const FieldDescriptor * field) const2906 bool Reflection::IsInlinedStringDonated(const Message& message,
2907                                         const FieldDescriptor* field) const {
2908   uint32_t index = schema_.InlinedStringIndex(field);
2909   ABSL_DCHECK_GT(index, 0u);
2910   return IsIndexInHasBitSet(GetInlinedStringDonatedArray(message), index);
2911 }
2912 
SetInlinedStringDonated(uint32_t index,uint32_t * array)2913 inline void SetInlinedStringDonated(uint32_t index, uint32_t* array) {
2914   array[index / 32] |= (static_cast<uint32_t>(1) << (index % 32));
2915 }
2916 
ClearInlinedStringDonated(uint32_t index,uint32_t * array)2917 inline void ClearInlinedStringDonated(uint32_t index, uint32_t* array) {
2918   array[index / 32] &= ~(static_cast<uint32_t>(1) << (index % 32));
2919 }
2920 
SwapInlinedStringDonated(Message * lhs,Message * rhs,const FieldDescriptor * field) const2921 void Reflection::SwapInlinedStringDonated(Message* lhs, Message* rhs,
2922                                           const FieldDescriptor* field) const {
2923   Arena* lhs_arena = lhs->GetArena();
2924   Arena* rhs_arena = rhs->GetArena();
2925   // If arenas differ, inined string fields are swapped by copying values.
2926   // Donation status should not be swapped.
2927   if (lhs_arena != rhs_arena) {
2928     return;
2929   }
2930   bool lhs_donated = IsInlinedStringDonated(*lhs, field);
2931   bool rhs_donated = IsInlinedStringDonated(*rhs, field);
2932   if (lhs_donated == rhs_donated) {
2933     return;
2934   }
2935   // If one is undonated, both must have already registered ArenaDtor.
2936   uint32_t* lhs_array = MutableInlinedStringDonatedArray(lhs);
2937   uint32_t* rhs_array = MutableInlinedStringDonatedArray(rhs);
2938   ABSL_CHECK_EQ(lhs_array[0] & 0x1u, 0u);
2939   ABSL_CHECK_EQ(rhs_array[0] & 0x1u, 0u);
2940   // Swap donation status bit.
2941   uint32_t index = schema_.InlinedStringIndex(field);
2942   ABSL_DCHECK_GT(index, 0u);
2943   if (rhs_donated) {
2944     SetInlinedStringDonated(index, lhs_array);
2945     ClearInlinedStringDonated(index, rhs_array);
2946   } else {  // lhs_donated
2947     ClearInlinedStringDonated(index, lhs_array);
2948     SetInlinedStringDonated(index, rhs_array);
2949   }
2950 }
2951 
2952 // Simple accessors for manipulating has_bits_.
HasFieldSingular(const Message & message,const FieldDescriptor * field) const2953 bool Reflection::HasFieldSingular(const Message& message,
2954                                   const FieldDescriptor* field) const {
2955   ABSL_DCHECK(!field->options().weak());
2956   if (schema_.HasBitIndex(field) != static_cast<uint32_t>(-1)) {
2957     return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field));
2958   }
2959 
2960   // proto3: no has-bits. All fields present except messages, which are
2961   // present only if their message-field pointer is non-null.
2962   if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2963     return !schema_.IsDefaultInstance(message) &&
2964            GetRaw<const Message*>(message, field) != nullptr;
2965   } else {
2966     // Non-message field (and non-oneof, since that was handled in HasField()
2967     // before calling us), and singular (again, checked in HasField). So, this
2968     // field must be a scalar.
2969 
2970     // Scalar primitive (numeric or string/bytes) fields are present if
2971     // their value is non-zero (numeric) or non-empty (string/bytes). N.B.:
2972     // we must use this definition here, rather than the "scalar fields
2973     // always present" in the proto3 docs, because MergeFrom() semantics
2974     // require presence as "present on wire", and reflection-based merge
2975     // (which uses HasField()) needs to be consistent with this.
2976     switch (field->cpp_type()) {
2977       case FieldDescriptor::CPPTYPE_STRING:
2978         switch (field->cpp_string_type()) {
2979           case FieldDescriptor::CppStringType::kCord:
2980             return !GetField<const absl::Cord>(message, field).empty();
2981           case FieldDescriptor::CppStringType::kView:
2982           case FieldDescriptor::CppStringType::kString: {
2983             if (IsInlined(field)) {
2984               return !GetField<InlinedStringField>(message, field)
2985                           .GetNoArena()
2986                           .empty();
2987             }
2988 
2989             return GetField<ArenaStringPtr>(message, field).Get().size() > 0;
2990           }
2991         }
2992         internal::Unreachable();
2993       case FieldDescriptor::CPPTYPE_BOOL:
2994         return GetRaw<bool>(message, field) != false;
2995       case FieldDescriptor::CPPTYPE_INT32:
2996         return GetRaw<int32_t>(message, field) != 0;
2997       case FieldDescriptor::CPPTYPE_INT64:
2998         return GetRaw<int64_t>(message, field) != 0;
2999       case FieldDescriptor::CPPTYPE_UINT32:
3000         return GetRaw<uint32_t>(message, field) != 0;
3001       case FieldDescriptor::CPPTYPE_UINT64:
3002         return GetRaw<uint64_t>(message, field) != 0;
3003       case FieldDescriptor::CPPTYPE_FLOAT:
3004         static_assert(sizeof(uint32_t) == sizeof(float),
3005                       "Code assumes uint32_t and float are the same size.");
3006         return GetRaw<uint32_t>(message, field) != 0;
3007       case FieldDescriptor::CPPTYPE_DOUBLE:
3008         static_assert(sizeof(uint64_t) == sizeof(double),
3009                       "Code assumes uint64_t and double are the same size.");
3010         return GetRaw<uint64_t>(message, field) != 0;
3011       case FieldDescriptor::CPPTYPE_ENUM:
3012         return GetRaw<int>(message, field) != 0;
3013       case FieldDescriptor::CPPTYPE_MESSAGE:
3014         // handled above; avoid warning
3015         break;
3016     }
3017     ABSL_LOG(FATAL) << "Reached impossible case in HasFieldSingular().";
3018     return false;
3019   }
3020 }
3021 
SetHasBit(Message * message,const FieldDescriptor * field) const3022 void Reflection::SetHasBit(Message* message,
3023                            const FieldDescriptor* field) const {
3024   ABSL_DCHECK(!field->options().weak());
3025   const uint32_t index = schema_.HasBitIndex(field);
3026   if (index == static_cast<uint32_t>(-1)) return;
3027   MutableHasBits(message)[index / 32] |=
3028       (static_cast<uint32_t>(1) << (index % 32));
3029 }
3030 
ClearHasBit(Message * message,const FieldDescriptor * field) const3031 void Reflection::ClearHasBit(Message* message,
3032                              const FieldDescriptor* field) const {
3033   ABSL_DCHECK(!field->options().weak());
3034   const uint32_t index = schema_.HasBitIndex(field);
3035   if (index == static_cast<uint32_t>(-1)) return;
3036   MutableHasBits(message)[index / 32] &=
3037       ~(static_cast<uint32_t>(1) << (index % 32));
3038 }
3039 
SwapHasBit(Message * message1,Message * message2,const FieldDescriptor * field) const3040 void Reflection::SwapHasBit(Message* message1, Message* message2,
3041                             const FieldDescriptor* field) const {
3042   ABSL_DCHECK(!field->options().weak());
3043   if (!schema_.HasHasbits()) {
3044     return;
3045   }
3046   bool temp_is_present = HasFieldSingular(*message1, field);
3047   if (HasFieldSingular(*message2, field)) {
3048     SetHasBit(message1, field);
3049   } else {
3050     ClearHasBit(message1, field);
3051   }
3052   if (temp_is_present) {
3053     SetHasBit(message2, field);
3054   } else {
3055     ClearHasBit(message2, field);
3056   }
3057 }
3058 
HasOneof(const Message & message,const OneofDescriptor * oneof_descriptor) const3059 bool Reflection::HasOneof(const Message& message,
3060                           const OneofDescriptor* oneof_descriptor) const {
3061   if (oneof_descriptor->is_synthetic()) {
3062     return HasField(message, oneof_descriptor->field(0));
3063   }
3064   return (GetOneofCase(message, oneof_descriptor) > 0);
3065 }
3066 
SetOneofCase(Message * message,const FieldDescriptor * field) const3067 void Reflection::SetOneofCase(Message* message,
3068                               const FieldDescriptor* field) const {
3069   *MutableOneofCase(message, field->containing_oneof()) = field->number();
3070 }
3071 
ClearOneofField(Message * message,const FieldDescriptor * field) const3072 void Reflection::ClearOneofField(Message* message,
3073                                  const FieldDescriptor* field) const {
3074   if (HasOneofField(*message, field)) {
3075     ClearOneof(message, field->containing_oneof());
3076   }
3077 }
3078 
ClearOneof(Message * message,const OneofDescriptor * oneof_descriptor) const3079 void Reflection::ClearOneof(Message* message,
3080                             const OneofDescriptor* oneof_descriptor) const {
3081   if (oneof_descriptor->is_synthetic()) {
3082     ClearField(message, oneof_descriptor->field(0));
3083     return;
3084   }
3085   // TODO: Consider to cache the unused object instead of deleting
3086   // it. It will be much faster if an application switches a lot from
3087   // a few oneof fields.  Time/space tradeoff
3088   uint32_t oneof_case = GetOneofCase(*message, oneof_descriptor);
3089   if (oneof_case > 0) {
3090     const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
3091     if (message->GetArena() == nullptr) {
3092       switch (field->cpp_type()) {
3093         case FieldDescriptor::CPPTYPE_STRING: {
3094           switch (field->cpp_string_type()) {
3095             case FieldDescriptor::CppStringType::kCord:
3096               delete *MutableRaw<absl::Cord*>(message, field);
3097               break;
3098             case FieldDescriptor::CppStringType::kView:
3099             case FieldDescriptor::CppStringType::kString: {
3100               // Oneof string fields are never set as a default instance.
3101               // We just need to pass some arbitrary default string to make it
3102               // work. This allows us to not have the real default accessible
3103               // from reflection.
3104               MutableField<ArenaStringPtr>(message, field)->Destroy();
3105               break;
3106             }
3107           }
3108           break;
3109         }
3110 
3111         case FieldDescriptor::CPPTYPE_MESSAGE:
3112           delete *MutableRaw<Message*>(message, field);
3113           break;
3114         default:
3115           break;
3116       }
3117     }
3118 
3119     *MutableOneofCase(message, oneof_descriptor) = 0;
3120   }
3121 }
3122 
3123 #define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE)                                  \
3124   template <>                                                              \
3125   const RepeatedField<TYPE>& Reflection::GetRepeatedFieldInternal<TYPE>(   \
3126       const Message& message, const FieldDescriptor* field) const {        \
3127     return *static_cast<const RepeatedField<TYPE>*>(                       \
3128         GetRawRepeatedField(message, field, CPPTYPE, CTYPE, nullptr));     \
3129   }                                                                        \
3130                                                                            \
3131   template <>                                                              \
3132   RepeatedField<TYPE>* Reflection::MutableRepeatedFieldInternal<TYPE>(     \
3133       Message * message, const FieldDescriptor* field) const {             \
3134     return static_cast<RepeatedField<TYPE>*>(                              \
3135         MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, nullptr)); \
3136   }
3137 
3138 HANDLE_TYPE(int32_t, FieldDescriptor::CPPTYPE_INT32, -1);
3139 HANDLE_TYPE(int64_t, FieldDescriptor::CPPTYPE_INT64, -1);
3140 HANDLE_TYPE(uint32_t, FieldDescriptor::CPPTYPE_UINT32, -1);
3141 HANDLE_TYPE(uint64_t, FieldDescriptor::CPPTYPE_UINT64, -1);
3142 HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1);
3143 HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1);
3144 HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1);
3145 
3146 
3147 #undef HANDLE_TYPE
3148 
GetRawRepeatedString(const Message & message,const FieldDescriptor * field,bool is_string) const3149 const void* Reflection::GetRawRepeatedString(const Message& message,
3150                                              const FieldDescriptor* field,
3151                                              bool is_string) const {
3152   (void)is_string;  // Parameter is used by Google-internal code.
3153   return GetRawRepeatedField(message, field, FieldDescriptor::CPPTYPE_STRING,
3154                              FieldOptions::STRING, nullptr);
3155 }
3156 
MutableRawRepeatedString(Message * message,const FieldDescriptor * field,bool is_string) const3157 void* Reflection::MutableRawRepeatedString(Message* message,
3158                                            const FieldDescriptor* field,
3159                                            bool is_string) const {
3160   (void)is_string;  // Parameter is used by Google-internal code.
3161   return MutableRawRepeatedField(message, field,
3162                                  FieldDescriptor::CPPTYPE_STRING,
3163                                  FieldOptions::STRING, nullptr);
3164 }
3165 
3166 // Template implementations of basic accessors.  Inline because each
3167 // template instance is only called from one location.  These are
3168 // used for all types except messages.
3169 template <typename Type>
GetField(const Message & message,const FieldDescriptor * field) const3170 const Type& Reflection::GetField(const Message& message,
3171                                  const FieldDescriptor* field) const {
3172   return GetRaw<Type>(message, field);
3173 }
3174 
3175 template <typename Type>
SetField(Message * message,const FieldDescriptor * field,const Type & value) const3176 void Reflection::SetField(Message* message, const FieldDescriptor* field,
3177                           const Type& value) const {
3178   bool real_oneof = schema_.InRealOneof(field);
3179   if (real_oneof && !HasOneofField(*message, field)) {
3180     ClearOneof(message, field->containing_oneof());
3181   }
3182   *MutableRaw<Type>(message, field) = value;
3183   real_oneof ? SetOneofCase(message, field) : SetHasBit(message, field);
3184 }
3185 
3186 template <typename Type>
MutableField(Message * message,const FieldDescriptor * field) const3187 Type* Reflection::MutableField(Message* message,
3188                                const FieldDescriptor* field) const {
3189   schema_.InRealOneof(field) ? SetOneofCase(message, field)
3190                              : SetHasBit(message, field);
3191   return MutableRaw<Type>(message, field);
3192 }
3193 
3194 template <typename Type>
GetRepeatedField(const Message & message,const FieldDescriptor * field,int index) const3195 const Type& Reflection::GetRepeatedField(const Message& message,
3196                                          const FieldDescriptor* field,
3197                                          int index) const {
3198   return GetRaw<RepeatedField<Type> >(message, field).Get(index);
3199 }
3200 
3201 template <typename Type>
GetRepeatedPtrField(const Message & message,const FieldDescriptor * field,int index) const3202 const Type& Reflection::GetRepeatedPtrField(const Message& message,
3203                                             const FieldDescriptor* field,
3204                                             int index) const {
3205   return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
3206 }
3207 
3208 template <typename Type>
SetRepeatedField(Message * message,const FieldDescriptor * field,int index,Type value) const3209 void Reflection::SetRepeatedField(Message* message,
3210                                   const FieldDescriptor* field, int index,
3211                                   Type value) const {
3212   MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
3213 }
3214 
3215 template <typename Type>
MutableRepeatedField(Message * message,const FieldDescriptor * field,int index) const3216 Type* Reflection::MutableRepeatedField(Message* message,
3217                                        const FieldDescriptor* field,
3218                                        int index) const {
3219   RepeatedPtrField<Type>* repeated =
3220       MutableRaw<RepeatedPtrField<Type> >(message, field);
3221   return repeated->Mutable(index);
3222 }
3223 
3224 template <typename Type>
AddField(Message * message,const FieldDescriptor * field,const Type & value) const3225 void Reflection::AddField(Message* message, const FieldDescriptor* field,
3226                           const Type& value) const {
3227   MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
3228 }
3229 
3230 template <typename Type>
AddField(Message * message,const FieldDescriptor * field) const3231 Type* Reflection::AddField(Message* message,
3232                            const FieldDescriptor* field) const {
3233   RepeatedPtrField<Type>* repeated =
3234       MutableRaw<RepeatedPtrField<Type> >(message, field);
3235   return repeated->Add();
3236 }
3237 
GetMessageFactory() const3238 MessageFactory* Reflection::GetMessageFactory() const {
3239   return message_factory_;
3240 }
3241 
RepeatedFieldData(const Message & message,const FieldDescriptor * field,FieldDescriptor::CppType cpp_type,const Descriptor * message_type) const3242 const void* Reflection::RepeatedFieldData(
3243     const Message& message, const FieldDescriptor* field,
3244     FieldDescriptor::CppType cpp_type, const Descriptor* message_type) const {
3245   ABSL_CHECK(field->is_repeated());
3246   ABSL_CHECK(field->cpp_type() == cpp_type ||
3247              (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
3248               cpp_type == FieldDescriptor::CPPTYPE_INT32))
3249       << "The type parameter T in RepeatedFieldRef<T> API doesn't match "
3250       << "the actual field type (for enums T should be the generated enum "
3251       << "type or int32_t).";
3252   if (message_type != nullptr) {
3253     ABSL_CHECK_EQ(message_type, field->message_type());
3254   }
3255   if (field->is_extension()) {
3256     return GetExtensionSet(message).GetRawRepeatedField(
3257         field->number(), internal::DefaultRawPtr());
3258   } else {
3259     return &GetRawNonOneof<char>(message, field);
3260   }
3261 }
3262 
RepeatedFieldData(Message * message,const FieldDescriptor * field,FieldDescriptor::CppType cpp_type,const Descriptor * message_type) const3263 void* Reflection::RepeatedFieldData(Message* message,
3264                                     const FieldDescriptor* field,
3265                                     FieldDescriptor::CppType cpp_type,
3266                                     const Descriptor* message_type) const {
3267   ABSL_CHECK(field->is_repeated());
3268   ABSL_CHECK(field->cpp_type() == cpp_type ||
3269              (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
3270               cpp_type == FieldDescriptor::CPPTYPE_INT32))
3271       << "The type parameter T in RepeatedFieldRef<T> API doesn't match "
3272       << "the actual field type (for enums T should be the generated enum "
3273       << "type or int32_t).";
3274   if (message_type != nullptr) {
3275     ABSL_CHECK_EQ(message_type, field->message_type());
3276   }
3277   if (field->is_extension()) {
3278     return MutableExtensionSet(message)->MutableRawRepeatedField(
3279         field->number(), field->type(), field->is_packed(), field);
3280   } else {
3281     return MutableRawNonOneof<char>(message, field);
3282   }
3283 }
3284 
MutableMapData(Message * message,const FieldDescriptor * field) const3285 MapFieldBase* Reflection::MutableMapData(Message* message,
3286                                          const FieldDescriptor* field) const {
3287   USAGE_CHECK(IsMapFieldInApi(field), GetMapData, "Field is not a map field.");
3288   return MutableRaw<MapFieldBase>(message, field);
3289 }
3290 
GetMapData(const Message & message,const FieldDescriptor * field) const3291 const MapFieldBase* Reflection::GetMapData(const Message& message,
3292                                            const FieldDescriptor* field) const {
3293   USAGE_CHECK(IsMapFieldInApi(field), GetMapData, "Field is not a map field.");
3294   return &(GetRaw<MapFieldBase>(message, field));
3295 }
3296 
3297 template <typename T>
AlignTo(uint32_t v)3298 static uint32_t AlignTo(uint32_t v) {
3299   return (v + alignof(T) - 1) & ~(alignof(T) - 1);
3300 }
3301 
GetFastParseFunction(internal::TcParseFunction func)3302 static internal::TailCallParseFunc GetFastParseFunction(
3303     internal::TcParseFunction func) {
3304 #define PROTOBUF_TC_PARSE_FUNCTION_X(value) internal::TcParser::value,
3305   static constexpr internal::TailCallParseFunc kFuncs[] = {
3306       {}, PROTOBUF_TC_PARSE_FUNCTION_LIST};
3307 #undef PROTOBUF_TC_PARSE_FUNCTION_X
3308   const int index = static_cast<int>(func);
3309   if (index < 0 || index >= std::end(kFuncs) - std::begin(kFuncs) ||
3310       kFuncs[index] == nullptr) {
3311     ABSL_DLOG(FATAL) << "Failed to find function: " << static_cast<int>(func);
3312     // Let's not crash in opt, just in case.
3313     // MiniParse is always a valid parser.
3314     return &internal::TcParser::MiniParse;
3315   }
3316   return kFuncs[index];
3317 }
3318 
PopulateTcParseFastEntries(const internal::TailCallTableInfo & table_info,TcParseTableBase::FastFieldEntry * fast_entries) const3319 void Reflection::PopulateTcParseFastEntries(
3320     const internal::TailCallTableInfo& table_info,
3321     TcParseTableBase::FastFieldEntry* fast_entries) const {
3322   for (const auto& fast_field : table_info.fast_path_fields) {
3323     if (auto* nonfield = fast_field.AsNonField()) {
3324       // No field, but still a special entry.
3325       *fast_entries++ = {GetFastParseFunction(nonfield->func),
3326                          {nonfield->coded_tag, nonfield->nonfield_info}};
3327     } else if (auto* as_field = fast_field.AsField()) {
3328       *fast_entries++ = {
3329           GetFastParseFunction(as_field->func),
3330           {as_field->coded_tag, as_field->hasbit_idx, as_field->aux_idx,
3331            static_cast<uint16_t>(schema_.GetFieldOffset(as_field->field))}};
3332     } else {
3333       ABSL_DCHECK(fast_field.is_empty());
3334       // No fast entry here. Use mini parser.
3335       *fast_entries++ = {internal::TcParser::MiniParse, {}};
3336     }
3337   }
3338 }
3339 
PopulateTcParseLookupTable(const internal::TailCallTableInfo & table_info,uint16_t * lookup_table)3340 static void PopulateTcParseLookupTable(
3341     const internal::TailCallTableInfo& table_info, uint16_t* lookup_table) {
3342   for (const auto& entry_block : table_info.num_to_entry_table.blocks) {
3343     *lookup_table++ = entry_block.first_fnum & 0xFFFF;
3344     *lookup_table++ = entry_block.first_fnum >> 16;
3345     *lookup_table++ = entry_block.entries.size();
3346     for (auto se16 : entry_block.entries) {
3347       *lookup_table++ = se16.skipmap;
3348       *lookup_table++ = se16.field_entry_offset;
3349     }
3350   }
3351   *lookup_table++ = 0xFFFF;
3352   *lookup_table++ = 0xFFFF;
3353 }
3354 
PopulateTcParseEntries(internal::TailCallTableInfo & table_info,TcParseTableBase::FieldEntry * entries) const3355 void Reflection::PopulateTcParseEntries(
3356     internal::TailCallTableInfo& table_info,
3357     TcParseTableBase::FieldEntry* entries) const {
3358   for (const auto& entry : table_info.field_entries) {
3359     const FieldDescriptor* field = entry.field;
3360     if (field->type() == field->TYPE_ENUM &&
3361         (entry.type_card & internal::field_layout::kTvMask) ==
3362             internal::field_layout::kTvEnum &&
3363         table_info.aux_entries[entry.aux_idx].type ==
3364             internal::TailCallTableInfo::kEnumValidator) {
3365       // Mini parse can't handle it. Fallback to reflection.
3366       *entries = {};
3367       table_info.aux_entries[entry.aux_idx] = {};
3368     } else {
3369       const OneofDescriptor* oneof = field->real_containing_oneof();
3370       entries->offset = schema_.GetFieldOffset(field);
3371       if (oneof != nullptr) {
3372         entries->has_idx = schema_.oneof_case_offset_ + 4 * oneof->index();
3373       } else if (schema_.HasHasbits()) {
3374         entries->has_idx =
3375             static_cast<int>(8 * schema_.HasBitsOffset() + entry.hasbit_idx);
3376       } else {
3377         entries->has_idx = 0;
3378       }
3379       entries->aux_idx = entry.aux_idx;
3380       entries->type_card = entry.type_card;
3381     }
3382 
3383     ++entries;
3384   }
3385 }
3386 
PopulateTcParseFieldAux(const internal::TailCallTableInfo & table_info,TcParseTableBase::FieldAux * field_aux) const3387 void Reflection::PopulateTcParseFieldAux(
3388     const internal::TailCallTableInfo& table_info,
3389     TcParseTableBase::FieldAux* field_aux) const {
3390   for (const auto& aux_entry : table_info.aux_entries) {
3391     switch (aux_entry.type) {
3392       case internal::TailCallTableInfo::kNothing:
3393         *field_aux++ = {};
3394         break;
3395       case internal::TailCallTableInfo::kInlinedStringDonatedOffset:
3396         field_aux++->offset =
3397             static_cast<uint32_t>(schema_.inlined_string_donated_offset_);
3398         break;
3399       case internal::TailCallTableInfo::kSplitOffset:
3400         field_aux++->offset = schema_.SplitOffset();
3401         break;
3402       case internal::TailCallTableInfo::kSplitSizeof:
3403         field_aux++->offset = schema_.SizeofSplit();
3404         break;
3405       case internal::TailCallTableInfo::kSubTable:
3406       case internal::TailCallTableInfo::kSubMessageWeak:
3407       case internal::TailCallTableInfo::kMessageVerifyFunc:
3408       case internal::TailCallTableInfo::kSelfVerifyFunc:
3409         ABSL_LOG(FATAL) << "Not supported";
3410         break;
3411       case internal::TailCallTableInfo::kMapAuxInfo:
3412         // Default constructed info, which causes MpMap to call the fallback.
3413         // DynamicMessage uses DynamicMapField, which uses variant keys and
3414         // values. TcParser does not support them yet, so mark the field as
3415         // unsupported to fallback to reflection.
3416         field_aux++->map_info = internal::MapAuxInfo{};
3417         break;
3418       case internal::TailCallTableInfo::kSubMessage:
3419         field_aux++->message_default_p =
3420             GetDefaultMessageInstance(aux_entry.field);
3421         break;
3422       case internal::TailCallTableInfo::kEnumRange:
3423         field_aux++->enum_range = {aux_entry.enum_range.start,
3424                                    aux_entry.enum_range.size};
3425         break;
3426       case internal::TailCallTableInfo::kEnumValidator:
3427         ABSL_LOG(FATAL) << "Not supported.";
3428         break;
3429       case internal::TailCallTableInfo::kNumericOffset:
3430         field_aux++->offset = aux_entry.offset;
3431         break;
3432     }
3433   }
3434 }
3435 
3436 
CreateTcParseTable() const3437 const internal::TcParseTableBase* Reflection::CreateTcParseTable() const {
3438   using TcParseTableBase = internal::TcParseTableBase;
3439 
3440   constexpr int kNoHasbit = -1;
3441   std::vector<internal::TailCallTableInfo::FieldOptions> fields;
3442   fields.reserve(descriptor_->field_count());
3443   for (int i = 0; i < descriptor_->field_count(); ++i) {
3444     auto* field = descriptor_->field(i);
3445     const bool is_inlined = IsInlined(field);
3446     fields.push_back({
3447         field,  //
3448         static_cast<int>(schema_.HasBitIndex(field)),
3449         1.f,  // All fields are assumed present.
3450         GetLazyStyle(field),
3451         is_inlined,
3452         // Only LITE can be implicitly weak.
3453         /* is_implicitly_weak */ false,
3454         // We could change this to use direct table.
3455         // Might be easier to do when all messages support TDP.
3456         /* use_direct_tcparser_table */ false,
3457         schema_.IsSplit(field),
3458         is_inlined ? static_cast<int>(schema_.InlinedStringIndex(field))
3459                    : kNoHasbit,
3460     });
3461   }
3462   std::sort(fields.begin(), fields.end(), [](const auto& a, const auto& b) {
3463     return a.field->number() < b.field->number();
3464   });
3465 
3466   internal::TailCallTableInfo table_info(
3467       descriptor_,
3468       {
3469           /* is_lite */ false,
3470           /* uses_codegen */ false,
3471           /* should_profile_driven_cluster_aux_table */ false,
3472       },
3473       fields);
3474 
3475   const size_t fast_entries_count = table_info.fast_path_fields.size();
3476   ABSL_CHECK_EQ(static_cast<int>(fast_entries_count),
3477                 1 << table_info.table_size_log2);
3478   const uint16_t lookup_table_offset = AlignTo<uint16_t>(
3479       sizeof(TcParseTableBase) +
3480       fast_entries_count * sizeof(TcParseTableBase::FastFieldEntry));
3481   const uint32_t field_entry_offset = AlignTo<TcParseTableBase::FieldEntry>(
3482       lookup_table_offset +
3483       sizeof(uint16_t) * table_info.num_to_entry_table.size16());
3484   const uint32_t aux_offset = AlignTo<TcParseTableBase::FieldAux>(
3485       field_entry_offset +
3486       sizeof(TcParseTableBase::FieldEntry) * fields.size());
3487 
3488   int byte_size =
3489       aux_offset +
3490       sizeof(TcParseTableBase::FieldAux) * table_info.aux_entries.size() +
3491       sizeof(char) * table_info.field_name_data.size();
3492 
3493   void* p = ::operator new(byte_size);
3494   auto* res = ::new (p) TcParseTableBase{
3495       static_cast<uint16_t>(schema_.HasHasbits() ? schema_.HasBitsOffset() : 0),
3496       schema_.HasExtensionSet()
3497           ? static_cast<uint16_t>(schema_.GetExtensionSetOffset())
3498           : uint16_t{0},
3499       static_cast<uint32_t>(fields.empty() ? 0 : fields.back().field->number()),
3500       static_cast<uint8_t>((fast_entries_count - 1) << 3),
3501       lookup_table_offset,
3502       table_info.num_to_entry_table.skipmap32,
3503       field_entry_offset,
3504       static_cast<uint16_t>(fields.size()),
3505       static_cast<uint16_t>(table_info.aux_entries.size()),
3506       aux_offset,
3507       schema_.default_instance_->GetClassData(),
3508       nullptr,
3509       GetFastParseFunction(table_info.fallback_function)
3510 #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
3511           ,
3512       nullptr
3513 #endif  // PROTOBUF_PREFETCH_PARSE_TABLE
3514   };
3515 #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
3516   // We'll prefetch `to_prefetch->to_prefetch` unconditionally to avoid
3517   // branches. Here we don't know which field is the hottest, so set the pointer
3518   // to itself to avoid nullptr.
3519   res->to_prefetch = res;
3520 #endif  // PROTOBUF_PREFETCH_PARSE_TABLE
3521 
3522   // Now copy the rest of the payloads
3523   PopulateTcParseFastEntries(table_info, res->fast_entry(0));
3524 
3525   PopulateTcParseLookupTable(table_info, res->field_lookup_begin());
3526 
3527   PopulateTcParseEntries(table_info, res->field_entries_begin());
3528 
3529   PopulateTcParseFieldAux(table_info, res->field_aux(0u));
3530 
3531   // Copy the name data.
3532   if (!table_info.field_name_data.empty()) {
3533     memcpy(res->name_data(), table_info.field_name_data.data(),
3534            table_info.field_name_data.size());
3535   }
3536   // Validation to make sure we used all the bytes correctly.
3537   ABSL_CHECK_EQ(res->name_data() + table_info.field_name_data.size() -
3538                     reinterpret_cast<char*>(res),
3539                 byte_size);
3540 
3541   return res;
3542 }
3543 
3544 namespace {
3545 
3546 // Helper function to transform migration schema into reflection schema.
MigrationToReflectionSchema(const Message * const * default_instance,const uint32_t * offsets,MigrationSchema migration_schema)3547 ReflectionSchema MigrationToReflectionSchema(
3548     const Message* const* default_instance, const uint32_t* offsets,
3549     MigrationSchema migration_schema) {
3550   ReflectionSchema result;
3551   result.default_instance_ = *default_instance;
3552   // First 9 offsets are offsets to the special fields. The following offsets
3553   // are the proto fields.
3554   //
3555   // TODO: Find a way to not encode sizeof_split_ in offsets.
3556   result.offsets_ = offsets + migration_schema.offsets_index + 8;
3557   result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index;
3558   result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0];
3559   result.metadata_offset_ = offsets[migration_schema.offsets_index + 1];
3560   result.extensions_offset_ = offsets[migration_schema.offsets_index + 2];
3561   result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3];
3562   result.object_size_ = migration_schema.object_size;
3563   result.weak_field_map_offset_ = offsets[migration_schema.offsets_index + 4];
3564   result.inlined_string_donated_offset_ =
3565       offsets[migration_schema.offsets_index + 5];
3566   result.split_offset_ = offsets[migration_schema.offsets_index + 6];
3567   result.sizeof_split_ = offsets[migration_schema.offsets_index + 7];
3568   result.inlined_string_indices_ =
3569       offsets + migration_schema.inlined_string_indices_index;
3570   return result;
3571 }
3572 
3573 }  // namespace
3574 
3575 class AssignDescriptorsHelper {
3576  public:
AssignDescriptorsHelper(MessageFactory * factory,const EnumDescriptor ** file_level_enum_descriptors,const MigrationSchema * schemas,const Message * const * default_instance_data,const uint32_t * offsets)3577   AssignDescriptorsHelper(MessageFactory* factory,
3578                           const EnumDescriptor** file_level_enum_descriptors,
3579                           const MigrationSchema* schemas,
3580                           const Message* const* default_instance_data,
3581                           const uint32_t* offsets)
3582       : factory_(factory),
3583         file_level_enum_descriptors_(file_level_enum_descriptors),
3584         schemas_(schemas),
3585         default_instance_data_(default_instance_data),
3586         offsets_(offsets) {}
3587 
AssignMessageDescriptor(const Descriptor * descriptor)3588   void AssignMessageDescriptor(const Descriptor* descriptor) {
3589     for (int i = 0; i < descriptor->nested_type_count(); i++) {
3590       AssignMessageDescriptor(descriptor->nested_type(i));
3591     }
3592 
3593     // If there is no default instance we only want to initialize the descriptor
3594     // without updating the reflection.
3595     if (default_instance_data_[0] != nullptr) {
3596       auto& class_data = default_instance_data_[0]->GetClassData()->full();
3597       // If there is no descriptor_table in the class data, then it is not
3598       // interested in receiving reflection information either.
3599       if (class_data.descriptor_table != nullptr) {
3600         class_data.descriptor = descriptor;
3601 
3602         class_data.reflection = OnShutdownDelete(new Reflection(
3603             descriptor,
3604             MigrationToReflectionSchema(default_instance_data_, offsets_,
3605                                         *schemas_),
3606             DescriptorPool::internal_generated_pool(), factory_));
3607       }
3608     }
3609     for (int i = 0; i < descriptor->enum_type_count(); i++) {
3610       AssignEnumDescriptor(descriptor->enum_type(i));
3611     }
3612     schemas_++;
3613     default_instance_data_++;
3614   }
3615 
AssignEnumDescriptor(const EnumDescriptor * descriptor)3616   void AssignEnumDescriptor(const EnumDescriptor* descriptor) {
3617     *file_level_enum_descriptors_ = descriptor;
3618     file_level_enum_descriptors_++;
3619   }
3620 
3621  private:
3622   MessageFactory* factory_;
3623   const EnumDescriptor** file_level_enum_descriptors_;
3624   const MigrationSchema* schemas_;
3625   const Message* const* default_instance_data_;
3626   const uint32_t* offsets_;
3627 };
3628 
3629 namespace {
3630 
AssignDescriptorsImpl(const DescriptorTable * table,bool eager)3631 void AssignDescriptorsImpl(const DescriptorTable* table, bool eager) {
3632   // Ensure the file descriptor is added to the pool.
3633   {
3634     // This only happens once per proto file. So a global mutex to serialize
3635     // calls to AddDescriptors.
3636     static absl::Mutex mu{absl::kConstInit};
3637     mu.Lock();
3638     AddDescriptors(table);
3639     mu.Unlock();
3640   }
3641   if (eager) {
3642     // Normally we do not want to eagerly build descriptors of our deps.
3643     // However if this proto is optimized for code size (ie using reflection)
3644     // and it has a message extending a custom option of a descriptor with that
3645     // message being optimized for code size as well. Building the descriptors
3646     // in this file requires parsing the serialized file descriptor, which now
3647     // requires parsing the message extension, which potentially requires
3648     // building the descriptor of the message extending one of the options.
3649     // However we are already updating descriptor pool under a lock. To prevent
3650     // this the compiler statically looks for this case and we just make sure we
3651     // first build the descriptors of all our dependencies, preventing the
3652     // deadlock.
3653     int num_deps = table->num_deps;
3654     for (int i = 0; i < num_deps; i++) {
3655       // In case of weak fields deps[i] could be null.
3656       if (table->deps[i]) {
3657         absl::call_once(*table->deps[i]->once, AssignDescriptorsImpl,
3658                         table->deps[i],
3659                         /*eager=*/true);
3660       }
3661     }
3662   }
3663 
3664   // Fill the arrays with pointers to descriptors and reflection classes.
3665   const FileDescriptor* file =
3666       DescriptorPool::internal_generated_pool()->FindFileByName(
3667           table->filename);
3668   ABSL_CHECK(file != nullptr);
3669 
3670   MessageFactory* factory = MessageFactory::generated_factory();
3671 
3672   AssignDescriptorsHelper helper(factory, table->file_level_enum_descriptors,
3673                                  table->schemas, table->default_instances,
3674                                  table->offsets);
3675 
3676   for (int i = 0; i < file->message_type_count(); i++) {
3677     helper.AssignMessageDescriptor(file->message_type(i));
3678   }
3679 
3680   for (int i = 0; i < file->enum_type_count(); i++) {
3681     helper.AssignEnumDescriptor(file->enum_type(i));
3682   }
3683   if (file->options().cc_generic_services()) {
3684     for (int i = 0; i < file->service_count(); i++) {
3685       table->file_level_service_descriptors[i] = file->service(i);
3686     }
3687   }
3688 }
3689 
MaybeInitializeLazyDescriptors(const DescriptorTable * table)3690 void MaybeInitializeLazyDescriptors(const DescriptorTable* table) {
3691   if (!IsLazilyInitializedFile(table->filename)) {
3692     // Ensure the generated pool has been lazily initialized.
3693     DescriptorPool::generated_pool();
3694   }
3695 }
3696 
AddDescriptorsImpl(const DescriptorTable * table)3697 void AddDescriptorsImpl(const DescriptorTable* table) {
3698   // Reflection refers to the default fields so make sure they are initialized.
3699   internal::InitProtobufDefaults();
3700   internal::InitializeFileDescriptorDefaultInstances();
3701   internal::InitializeLazyExtensionSet();
3702 
3703   // Ensure all dependent descriptors are registered to the generated descriptor
3704   // pool and message factory.
3705   int num_deps = table->num_deps;
3706   for (int i = 0; i < num_deps; i++) {
3707     // In case of weak fields deps[i] could be null.
3708     if (table->deps[i]) AddDescriptors(table->deps[i]);
3709   }
3710 
3711   // Register the descriptor of this file.
3712   DescriptorPool::InternalAddGeneratedFile(table->descriptor, table->size);
3713   MessageFactory::InternalRegisterGeneratedFile(table);
3714 }
3715 
3716 }  // namespace
3717 
3718 namespace internal {
3719 
AddDescriptors(const DescriptorTable * table)3720 void AddDescriptors(const DescriptorTable* table) {
3721   // AddDescriptors is not thread safe. Callers need to ensure calls are
3722   // properly serialized. This function is only called pre-main by global
3723   // descriptors and we can assume single threaded access or it's called
3724   // by AssignDescriptorImpl which uses a mutex to sequence calls.
3725   if (table->is_initialized) return;
3726   table->is_initialized = true;
3727   AddDescriptorsImpl(table);
3728 }
3729 
AssignDescriptorsOnceInnerCall(const DescriptorTable * table)3730 void AssignDescriptorsOnceInnerCall(const DescriptorTable* table) {
3731   MaybeInitializeLazyDescriptors(table);
3732   AssignDescriptorsImpl(table, table->is_eager);
3733 }
3734 
AssignDescriptors(const DescriptorTable * table)3735 void AssignDescriptors(const DescriptorTable* table) {
3736   absl::call_once(*table->once, [=] { AssignDescriptorsOnceInnerCall(table); });
3737 }
3738 
AddDescriptorsRunner(const DescriptorTable * table)3739 AddDescriptorsRunner::AddDescriptorsRunner(const DescriptorTable* table) {
3740   AddDescriptors(table);
3741 }
3742 
RegisterFileLevelMetadata(const DescriptorTable * table)3743 void RegisterFileLevelMetadata(const DescriptorTable* table) {
3744   AssignDescriptors(table);
3745   auto* file = DescriptorPool::internal_generated_pool()->FindFileByName(
3746       table->filename);
3747   auto defaults = table->default_instances;
3748   internal::cpp::VisitDescriptorsInFileOrder(file, [&](auto* desc) {
3749     MessageFactory::InternalRegisterGeneratedMessage(desc, *defaults);
3750     ++defaults;
3751     return std::false_type{};
3752   });
3753 }
3754 
UnknownFieldSetSerializer(const uint8_t * base,uint32_t offset,uint32_t,uint32_t,io::CodedOutputStream * output)3755 void UnknownFieldSetSerializer(const uint8_t* base, uint32_t offset,
3756                                uint32_t /*tag*/, uint32_t /*has_offset*/,
3757                                io::CodedOutputStream* output) {
3758   const void* ptr = base + offset;
3759   const InternalMetadata* metadata = static_cast<const InternalMetadata*>(ptr);
3760   if (metadata->have_unknown_fields()) {
3761     metadata->unknown_fields<UnknownFieldSet>(UnknownFieldSet::default_instance)
3762         .SerializeToCodedStream(output);
3763   }
3764 }
3765 
IsDescendant(Message & root,const Message & message)3766 bool IsDescendant(Message& root, const Message& message) {
3767   const Reflection* reflection = root.GetReflection();
3768   std::vector<const FieldDescriptor*> fields;
3769   reflection->ListFields(root, &fields);
3770 
3771   for (const auto* field : fields) {
3772     // Skip non-message fields.
3773     if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
3774 
3775     // Optional messages.
3776     if (!field->is_repeated()) {
3777       Message* sub_message = reflection->MutableMessage(&root, field);
3778       if (sub_message == &message || IsDescendant(*sub_message, message)) {
3779         return true;
3780       }
3781       continue;
3782     }
3783 
3784     // Repeated messages.
3785     if (!IsMapFieldInApi(field)) {
3786       int count = reflection->FieldSize(root, field);
3787       for (int i = 0; i < count; i++) {
3788         Message* sub_message =
3789             reflection->MutableRepeatedMessage(&root, field, i);
3790         if (sub_message == &message || IsDescendant(*sub_message, message)) {
3791           return true;
3792         }
3793       }
3794       continue;
3795     }
3796 
3797     // Map field: if accessed as repeated fields, messages are *copied* and
3798     // matching pointer won't work. Must directly access map.
3799     constexpr int kValIdx = 1;
3800     const FieldDescriptor* val_field = field->message_type()->field(kValIdx);
3801     // Skip map fields whose value type is not message.
3802     if (val_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
3803 
3804     MapIterator end = reflection->MapEnd(&root, field);
3805     for (auto iter = reflection->MapBegin(&root, field); iter != end; ++iter) {
3806       Message* sub_message = iter.MutableValueRef()->MutableMessageValue();
3807       if (sub_message == &message || IsDescendant(*sub_message, message)) {
3808         return true;
3809       }
3810     }
3811   }
3812 
3813   return false;
3814 }
3815 
SplitFieldHasExtraIndirection(const FieldDescriptor * field)3816 bool SplitFieldHasExtraIndirection(const FieldDescriptor* field) {
3817   return field->is_repeated();
3818 }
3819 
3820 #if defined(PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED)
GetPrototypeForWeakDescriptor(const DescriptorTable * table,int index,bool force_build)3821 const Message* GetPrototypeForWeakDescriptor(const DescriptorTable* table,
3822                                              int index, bool force_build) {
3823   // First, make sure we inject the surviving default instances.
3824   InitProtobufDefaults();
3825 
3826   // Now check if the table has it. If so, return it.
3827   if (const auto* msg = table->default_instances[index]) {
3828     return msg;
3829   }
3830 
3831   if (!force_build) {
3832     return nullptr;
3833   }
3834 
3835   // Fallback to dynamic messages.
3836   // Register the dep and generate the prototype via the generated pool.
3837   AssignDescriptors(table);
3838 
3839   const FileDescriptor* file =
3840       DescriptorPool::internal_generated_pool()->FindFileByName(
3841           table->filename);
3842 
3843   const Descriptor* descriptor = internal::cpp::VisitDescriptorsInFileOrder(
3844       file, [&](auto* desc) -> const Descriptor* {
3845         if (index == 0) return desc;
3846         --index;
3847         return nullptr;
3848       });
3849 
3850   return MessageFactory::generated_factory()->GetPrototype(descriptor);
3851 }
3852 #endif  // PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED
3853 
3854 }  // namespace internal
3855 }  // namespace protobuf
3856 }  // namespace google
3857 
3858 #include "google/protobuf/port_undef.inc"
3859