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


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:26