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