• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 // Author: kenton@google.com (Kenton Varda)
9 //  Based on original Protocol Buffers design by
10 //  Sanjay Ghemawat, Jeff Dean, and others.
11 //
12 // DynamicMessage is implemented by constructing a data structure which
13 // has roughly the same memory layout as a generated message would have.
14 // Then, we use Reflection to implement our reflection interface.  All
15 // the other operations we need to implement (e.g.  parsing, copying,
16 // etc.) are already implemented in terms of Reflection, so the rest is
17 // easy.
18 //
19 // The up side of this strategy is that it's very efficient.  We don't
20 // need to use hash_maps or generic representations of fields.  The
21 // down side is that this is a low-level memory management hack which
22 // can be tricky to get right.
23 //
24 // As mentioned in the header, we only expose a DynamicMessageFactory
25 // publicly, not the DynamicMessage class itself.  This is because
26 // GenericMessageReflection wants to have a pointer to a "default"
27 // copy of the class, with all fields initialized to their default
28 // values.  We only want to construct one of these per message type,
29 // so DynamicMessageFactory stores a cache of default messages for
30 // each type it sees (each unique Descriptor pointer).  The code
31 // refers to the "default" copy of the class as the "prototype".
32 //
33 // Note on memory allocation:  This module often calls "operator new()"
34 // to allocate untyped memory, rather than calling something like
35 // "new uint8_t[]".  This is because "operator new()" means "Give me some
36 // space which I can use as I please." while "new uint8_t[]" means "Give
37 // me an array of 8-bit integers.".  In practice, the later may return
38 // a pointer that is not aligned correctly for general use.  I believe
39 // Item 8 of "More Effective C++" discusses this in more detail, though
40 // I don't have the book on me right now so I'm not sure.
41 
42 #include "google/protobuf/dynamic_message.h"
43 
44 #include <algorithm>
45 #include <cstddef>
46 #include <cstdint>
47 #include <cstring>
48 #include <memory>
49 #include <new>
50 #include <string>
51 
52 #include "absl/log/absl_check.h"
53 #include "google/protobuf/arenastring.h"
54 #include "google/protobuf/descriptor.h"
55 #include "google/protobuf/descriptor.pb.h"
56 #include "google/protobuf/extension_set.h"
57 #include "google/protobuf/generated_message_reflection.h"
58 #include "google/protobuf/generated_message_util.h"
59 #include "google/protobuf/map_field.h"
60 #include "google/protobuf/message_lite.h"
61 #include "google/protobuf/repeated_field.h"
62 #include "google/protobuf/unknown_field_set.h"
63 #include "google/protobuf/wire_format.h"
64 
65 
66 // Must be included last.
67 #include "google/protobuf/port_def.inc"
68 
69 namespace google {
70 namespace protobuf {
71 
72 using internal::DynamicMapField;
73 using internal::ExtensionSet;
74 using internal::MapField;
75 
76 
77 using internal::ArenaStringPtr;
78 
79 // ===================================================================
80 // Some helper tables and functions...
81 
82 namespace {
83 
IsMapFieldInApi(const FieldDescriptor * field)84 bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); }
85 
86 
InRealOneof(const FieldDescriptor * field)87 inline bool InRealOneof(const FieldDescriptor* field) {
88   return field->real_containing_oneof() != nullptr;
89 }
90 
91 // Compute the byte size of the in-memory representation of the field.
FieldSpaceUsed(const FieldDescriptor * field)92 int FieldSpaceUsed(const FieldDescriptor* field) {
93   typedef FieldDescriptor FD;  // avoid line wrapping
94   if (field->label() == FD::LABEL_REPEATED) {
95     switch (field->cpp_type()) {
96       case FD::CPPTYPE_INT32:
97         return sizeof(RepeatedField<int32_t>);
98       case FD::CPPTYPE_INT64:
99         return sizeof(RepeatedField<int64_t>);
100       case FD::CPPTYPE_UINT32:
101         return sizeof(RepeatedField<uint32_t>);
102       case FD::CPPTYPE_UINT64:
103         return sizeof(RepeatedField<uint64_t>);
104       case FD::CPPTYPE_DOUBLE:
105         return sizeof(RepeatedField<double>);
106       case FD::CPPTYPE_FLOAT:
107         return sizeof(RepeatedField<float>);
108       case FD::CPPTYPE_BOOL:
109         return sizeof(RepeatedField<bool>);
110       case FD::CPPTYPE_ENUM:
111         return sizeof(RepeatedField<int>);
112       case FD::CPPTYPE_MESSAGE:
113         if (IsMapFieldInApi(field)) {
114           return sizeof(DynamicMapField);
115         } else {
116           return sizeof(RepeatedPtrField<Message>);
117         }
118 
119       case FD::CPPTYPE_STRING:
120         switch (field->cpp_string_type()) {
121           case FieldDescriptor::CppStringType::kCord:
122             return sizeof(RepeatedField<absl::Cord>);
123           case FieldDescriptor::CppStringType::kView:
124           case FieldDescriptor::CppStringType::kString:
125             return sizeof(RepeatedPtrField<std::string>);
126         }
127         break;
128     }
129   } else {
130     switch (field->cpp_type()) {
131       case FD::CPPTYPE_INT32:
132         return sizeof(int32_t);
133       case FD::CPPTYPE_INT64:
134         return sizeof(int64_t);
135       case FD::CPPTYPE_UINT32:
136         return sizeof(uint32_t);
137       case FD::CPPTYPE_UINT64:
138         return sizeof(uint64_t);
139       case FD::CPPTYPE_DOUBLE:
140         return sizeof(double);
141       case FD::CPPTYPE_FLOAT:
142         return sizeof(float);
143       case FD::CPPTYPE_BOOL:
144         return sizeof(bool);
145       case FD::CPPTYPE_ENUM:
146         return sizeof(int);
147 
148       case FD::CPPTYPE_MESSAGE:
149         return sizeof(Message*);
150 
151       case FD::CPPTYPE_STRING:
152         switch (field->cpp_string_type()) {
153           case FieldDescriptor::CppStringType::kCord:
154             return sizeof(absl::Cord);
155           case FieldDescriptor::CppStringType::kView:
156           case FieldDescriptor::CppStringType::kString:
157             return sizeof(ArenaStringPtr);
158         }
159         break;
160     }
161   }
162 
163   ABSL_DLOG(FATAL) << "Can't get here.";
164   return 0;
165 }
166 
DivideRoundingUp(int i,int j)167 inline int DivideRoundingUp(int i, int j) { return (i + (j - 1)) / j; }
168 
169 static const int kSafeAlignment = sizeof(uint64_t);
170 static const int kMaxOneofUnionSize = sizeof(uint64_t);
171 
AlignTo(int offset,int alignment)172 inline int AlignTo(int offset, int alignment) {
173   return DivideRoundingUp(offset, alignment) * alignment;
174 }
175 
176 // Rounds the given byte offset up to the next offset aligned such that any
177 // type may be stored at it.
AlignOffset(int offset)178 inline int AlignOffset(int offset) { return AlignTo(offset, kSafeAlignment); }
179 
180 #define bitsizeof(T) (sizeof(T) * 8)
181 
182 }  // namespace
183 
184 // ===================================================================
185 
186 class DynamicMessage final : public Message {
187  public:
188   // This should only be used by GetPrototypeNoLock() to avoid dead lock.
189   DynamicMessage(DynamicMessageFactory::TypeInfo* type_info, bool lock_factory);
190   DynamicMessage(const DynamicMessage&) = delete;
191   DynamicMessage& operator=(const DynamicMessage&) = delete;
192 
193   ~DynamicMessage() PROTOBUF_FINAL;
194 
195   // Called on the prototype after construction to initialize message fields.
196   // Cross linking the default instances allows for fast reflection access of
197   // unset message fields. Without it we would have to go to the MessageFactory
198   // to get the prototype, which is a much more expensive operation.
199   //
200   // Generated messages do not cross-link to avoid dynamic initialization of the
201   // global instances.
202   // Instead, they keep the default instances in the FieldDescriptor objects.
203   void CrossLinkPrototypes();
204 
205   // implements Message ----------------------------------------------
206 
207   const internal::ClassData* GetClassData() const PROTOBUF_FINAL;
208 
209 #if defined(__cpp_lib_destroying_delete) && defined(__cpp_sized_deallocation)
210   static void operator delete(DynamicMessage* msg, std::destroying_delete_t);
211 #else
212   // We actually allocate more memory than sizeof(*this) when this
213   // class's memory is allocated via the global operator new. Thus, we need to
214   // manually call the global operator delete. Calling the destructor is taken
215   // care of for us. This makes DynamicMessage compatible with -fsized-delete.
216   // It doesn't work for MSVC though.
217 #ifndef _MSC_VER
operator delete(void * ptr)218   static void operator delete(void* ptr) { ::operator delete(ptr); }
219 #endif  // !_MSC_VER
220 #endif
221 
222  private:
223   DynamicMessage(const DynamicMessageFactory::TypeInfo* type_info,
224                  Arena* arena);
225 
226   void SharedCtor(bool lock_factory);
227 
228   // Needed to get the offset of the internal metadata member.
229   friend class DynamicMessageFactory;
230 
231   bool is_prototype() const;
232 
OffsetToPointer(int offset)233   inline void* OffsetToPointer(int offset) {
234     return reinterpret_cast<uint8_t*>(this) + offset;
235   }
OffsetToPointer(int offset) const236   inline const void* OffsetToPointer(int offset) const {
237     return reinterpret_cast<const uint8_t*>(this) + offset;
238   }
239 
240   static void* NewImpl(const void* prototype, void* mem, Arena* arena);
241   static void DestroyImpl(MessageLite& ptr);
242 
243   void* MutableRaw(int i);
244   void* MutableExtensionsRaw();
245   void* MutableWeakFieldMapRaw();
246   void* MutableOneofCaseRaw(int i);
247   void* MutableOneofFieldRaw(const FieldDescriptor* f);
248 
249   const DynamicMessageFactory::TypeInfo* type_info_;
250   internal::CachedSize cached_byte_size_;
251 };
252 
253 struct DynamicMessageFactory::TypeInfo {
254   int has_bits_offset;
255   int oneof_case_offset;
256   int extensions_offset;
257 
258   // Not owned by the TypeInfo.
259   DynamicMessageFactory* factory;  // The factory that created this object.
260   const DescriptorPool* pool;      // The factory's DescriptorPool.
261 
262   // Warning:  The order in which the following pointers are defined is
263   //   important (the prototype must be deleted *before* the offsets).
264   std::unique_ptr<uint32_t[]> offsets;
265   std::unique_ptr<uint32_t[]> has_bits_indices;
266   int weak_field_map_offset;  // The offset for the weak_field_map;
267 
268   internal::ClassDataFull class_data = {
269       internal::ClassData{
270           nullptr,  // default_instance
271           nullptr,  // tc_table
272           nullptr,  // on_demand_register_arena_dtor
273           &DynamicMessage::IsInitializedImpl,
274           &DynamicMessage::MergeImpl,
275           internal::MessageCreator(),  // to be filled later
276           &DynamicMessage::DestroyImpl,
277           static_cast<void (MessageLite::*)()>(&DynamicMessage::ClearImpl),
278           DynamicMessage::ByteSizeLongImpl,
279           DynamicMessage::_InternalSerializeImpl,
280           PROTOBUF_FIELD_OFFSET(DynamicMessage, cached_byte_size_),
281           false,
282       },
283       &DynamicMessage::kDescriptorMethods,
284       nullptr,  // descriptor_table
285       nullptr,  // get_metadata_tracker
286   };
287 
288   TypeInfo() = default;
289 
~TypeInfogoogle::protobuf::DynamicMessageFactory::TypeInfo290   ~TypeInfo() {
291     delete class_data.prototype;
292     delete class_data.reflection;
293 
294     auto* type = class_data.descriptor;
295 
296     // Scribble the payload to prevent unsanitized opt builds from silently
297     // allowing use-after-free bugs where the factory is destroyed but the
298     // DynamicMessage instances are still used.
299     // This is a common bug with DynamicMessageFactory.
300     // NOTE: This must happen after deleting the prototype.
301     if (offsets != nullptr) {
302       std::fill_n(offsets.get(), type->field_count(), 0xCDCDCDCDu);
303     }
304     if (has_bits_indices != nullptr) {
305       std::fill_n(has_bits_indices.get(), type->field_count(), 0xCDCDCDCDu);
306     }
307   }
308 };
309 
DynamicMessage(const DynamicMessageFactory::TypeInfo * type_info,Arena * arena)310 DynamicMessage::DynamicMessage(const DynamicMessageFactory::TypeInfo* type_info,
311                                Arena* arena)
312     : Message(arena, type_info->class_data.base()),
313       type_info_(type_info),
314       cached_byte_size_(0) {
315   SharedCtor(true);
316 }
317 
DynamicMessage(DynamicMessageFactory::TypeInfo * type_info,bool lock_factory)318 DynamicMessage::DynamicMessage(DynamicMessageFactory::TypeInfo* type_info,
319                                bool lock_factory)
320     : Message(type_info->class_data.base()),
321       type_info_(type_info),
322       cached_byte_size_(0) {
323   // The prototype in type_info has to be set before creating the prototype
324   // instance on memory. e.g., message Foo { map<int32_t, Foo> a = 1; }. When
325   // creating prototype for Foo, prototype of the map entry will also be
326   // created, which needs the address of the prototype of Foo (the value in
327   // map). To break the cyclic dependency, we have to assign the address of
328   // prototype into type_info first.
329   type_info->class_data.prototype = this;
330   SharedCtor(lock_factory);
331 }
332 
MutableRaw(int i)333 inline void* DynamicMessage::MutableRaw(int i) {
334   return OffsetToPointer(type_info_->offsets[i]);
335 }
MutableExtensionsRaw()336 inline void* DynamicMessage::MutableExtensionsRaw() {
337   return OffsetToPointer(type_info_->extensions_offset);
338 }
MutableWeakFieldMapRaw()339 inline void* DynamicMessage::MutableWeakFieldMapRaw() {
340   return OffsetToPointer(type_info_->weak_field_map_offset);
341 }
MutableOneofCaseRaw(int i)342 inline void* DynamicMessage::MutableOneofCaseRaw(int i) {
343   return OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32_t) * i);
344 }
MutableOneofFieldRaw(const FieldDescriptor * f)345 inline void* DynamicMessage::MutableOneofFieldRaw(const FieldDescriptor* f) {
346   return OffsetToPointer(
347       type_info_->offsets[type_info_->class_data.descriptor->field_count() +
348                           f->containing_oneof()->index()]);
349 }
350 
SharedCtor(bool lock_factory)351 void DynamicMessage::SharedCtor(bool lock_factory) {
352   // We need to call constructors for various fields manually and set
353   // default values where appropriate.  We use placement new to call
354   // constructors.  If you haven't heard of placement new, I suggest Googling
355   // it now.  We use placement new even for primitive types that don't have
356   // constructors for consistency.  (In theory, placement new should be used
357   // any time you are trying to convert untyped memory to typed memory, though
358   // in practice that's not strictly necessary for types that don't have a
359   // constructor.)
360 
361   const Descriptor* descriptor = type_info_->class_data.descriptor;
362   Arena* arena = GetArena();
363   // Initialize oneof cases.
364   int oneof_count = 0;
365   for (int i = 0; i < descriptor->real_oneof_decl_count(); ++i) {
366     new (MutableOneofCaseRaw(oneof_count++)) uint32_t{0};
367   }
368 
369   if (type_info_->extensions_offset != -1) {
370     new (MutableExtensionsRaw()) ExtensionSet(arena);
371   }
372   for (int i = 0; i < descriptor->field_count(); i++) {
373     const FieldDescriptor* field = descriptor->field(i);
374     void* field_ptr = MutableRaw(i);
375     if (InRealOneof(field)) {
376       continue;
377     }
378     switch (field->cpp_type()) {
379 #define HANDLE_TYPE(CPPTYPE, TYPE)                         \
380   case FieldDescriptor::CPPTYPE_##CPPTYPE:                 \
381     if (!field->is_repeated()) {                           \
382       new (field_ptr) TYPE(field->default_value_##TYPE()); \
383     } else {                                               \
384       new (field_ptr) RepeatedField<TYPE>(arena);          \
385     }                                                      \
386     break;
387 
388       HANDLE_TYPE(INT32, int32_t);
389       HANDLE_TYPE(INT64, int64_t);
390       HANDLE_TYPE(UINT32, uint32_t);
391       HANDLE_TYPE(UINT64, uint64_t);
392       HANDLE_TYPE(DOUBLE, double);
393       HANDLE_TYPE(FLOAT, float);
394       HANDLE_TYPE(BOOL, bool);
395 #undef HANDLE_TYPE
396 
397       case FieldDescriptor::CPPTYPE_ENUM:
398         if (!field->is_repeated()) {
399           new (field_ptr) int{field->default_value_enum()->number()};
400         } else {
401           new (field_ptr) RepeatedField<int>(arena);
402         }
403         break;
404 
405       case FieldDescriptor::CPPTYPE_STRING:
406         switch (field->cpp_string_type()) {
407           case FieldDescriptor::CppStringType::kCord:
408             if (!field->is_repeated()) {
409               if (field->has_default_value()) {
410                 new (field_ptr) absl::Cord(field->default_value_string());
411               } else {
412                 new (field_ptr) absl::Cord;
413               }
414               if (arena != nullptr) {
415                 // Cord does not support arena so here we need to notify arena
416                 // to remove the data it allocated on the heap by calling its
417                 // destructor.
418                 arena->OwnDestructor(static_cast<absl::Cord*>(field_ptr));
419               }
420             } else {
421               new (field_ptr) RepeatedField<absl::Cord>(arena);
422               if (arena != nullptr) {
423                 // Needs to destroy Cord elements.
424                 arena->OwnDestructor(
425                     static_cast<RepeatedField<absl::Cord>*>(field_ptr));
426               }
427             }
428             break;
429           case FieldDescriptor::CppStringType::kView:
430           case FieldDescriptor::CppStringType::kString:
431             if (!field->is_repeated()) {
432               ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr();
433               asp->InitDefault();
434             } else {
435               new (field_ptr) RepeatedPtrField<std::string>(arena);
436             }
437             break;
438         }
439         break;
440 
441       case FieldDescriptor::CPPTYPE_MESSAGE: {
442         if (!field->is_repeated()) {
443           new (field_ptr) Message*(nullptr);
444         } else {
445           if (IsMapFieldInApi(field)) {
446             // We need to lock in most cases to avoid data racing. Only not lock
447             // when the constructor is called inside GetPrototype(), in which
448             // case we have already locked the factory.
449             if (lock_factory) {
450               if (arena != nullptr) {
451                 new (field_ptr) DynamicMapField(
452                     type_info_->factory->GetPrototype(field->message_type()),
453                     arena);
454               } else {
455                 new (field_ptr) DynamicMapField(
456                     type_info_->factory->GetPrototype(field->message_type()));
457               }
458             } else {
459               if (arena != nullptr) {
460                 new (field_ptr)
461                     DynamicMapField(type_info_->factory->GetPrototypeNoLock(
462                                         field->message_type()),
463                                     arena);
464               } else {
465                 new (field_ptr)
466                     DynamicMapField(type_info_->factory->GetPrototypeNoLock(
467                         field->message_type()));
468               }
469             }
470           } else {
471             new (field_ptr) RepeatedPtrField<Message>(arena);
472           }
473         }
474         break;
475       }
476     }
477   }
478 }
479 
is_prototype() const480 bool DynamicMessage::is_prototype() const {
481   return type_info_->class_data.prototype == this ||
482          // If type_info_->prototype is nullptr, then we must be constructing
483          // the prototype now, which means we must be the prototype.
484          type_info_->class_data.prototype == nullptr;
485 }
486 
487 #if defined(__cpp_lib_destroying_delete) && defined(__cpp_sized_deallocation)
operator delete(DynamicMessage * msg,std::destroying_delete_t)488 void DynamicMessage::operator delete(DynamicMessage* msg,
489                                      std::destroying_delete_t) {
490   const size_t size = msg->type_info_->class_data.allocation_size();
491   msg->~DynamicMessage();
492   ::operator delete(msg, size);
493 }
494 #endif
495 
~DynamicMessage()496 DynamicMessage::~DynamicMessage() {
497   const Descriptor* descriptor = type_info_->class_data.descriptor;
498 
499   _internal_metadata_.Delete<UnknownFieldSet>();
500 
501   if (type_info_->extensions_offset != -1) {
502     reinterpret_cast<ExtensionSet*>(MutableExtensionsRaw())->~ExtensionSet();
503   }
504 
505   // We need to manually run the destructors for repeated fields and strings,
506   // just as we ran their constructors in the DynamicMessage constructor.
507   // We also need to manually delete oneof fields if it is set and is string
508   // or message.
509   // Additionally, if any singular embedded messages have been allocated, we
510   // need to delete them, UNLESS we are the prototype message of this type,
511   // in which case any embedded messages are other prototypes and shouldn't
512   // be touched.
513   for (int i = 0; i < descriptor->field_count(); i++) {
514     const FieldDescriptor* field = descriptor->field(i);
515     if (InRealOneof(field)) {
516       void* field_ptr = MutableOneofCaseRaw(field->containing_oneof()->index());
517       if (*(reinterpret_cast<const int32_t*>(field_ptr)) == field->number()) {
518         field_ptr = MutableOneofFieldRaw(field);
519         if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
520           switch (field->cpp_string_type()) {
521             case FieldDescriptor::CppStringType::kCord:
522               delete *reinterpret_cast<absl::Cord**>(field_ptr);
523               break;
524             case FieldDescriptor::CppStringType::kView:
525             case FieldDescriptor::CppStringType::kString: {
526               reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy();
527               break;
528             }
529           }
530         } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
531             delete *reinterpret_cast<Message**>(field_ptr);
532         }
533       }
534       continue;
535     }
536     void* field_ptr = MutableRaw(i);
537 
538     if (field->is_repeated()) {
539       switch (field->cpp_type()) {
540 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                  \
541   case FieldDescriptor::CPPTYPE_##UPPERCASE:               \
542     reinterpret_cast<RepeatedField<LOWERCASE>*>(field_ptr) \
543         ->~RepeatedField<LOWERCASE>();                     \
544     break
545 
546         HANDLE_TYPE(INT32, int32_t);
547         HANDLE_TYPE(INT64, int64_t);
548         HANDLE_TYPE(UINT32, uint32_t);
549         HANDLE_TYPE(UINT64, uint64_t);
550         HANDLE_TYPE(DOUBLE, double);
551         HANDLE_TYPE(FLOAT, float);
552         HANDLE_TYPE(BOOL, bool);
553         HANDLE_TYPE(ENUM, int);
554 #undef HANDLE_TYPE
555 
556         case FieldDescriptor::CPPTYPE_STRING:
557           switch (field->cpp_string_type()) {
558             case FieldDescriptor::CppStringType::kCord:
559               reinterpret_cast<RepeatedField<absl::Cord>*>(field_ptr)
560                   ->~RepeatedField<absl::Cord>();
561               break;
562             case FieldDescriptor::CppStringType::kView:
563             case FieldDescriptor::CppStringType::kString:
564               reinterpret_cast<RepeatedPtrField<std::string>*>(field_ptr)
565                   ->~RepeatedPtrField<std::string>();
566               break;
567           }
568           break;
569 
570         case FieldDescriptor::CPPTYPE_MESSAGE:
571           if (IsMapFieldInApi(field)) {
572             reinterpret_cast<DynamicMapField*>(field_ptr)->~DynamicMapField();
573           } else {
574             reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr)
575                 ->~RepeatedPtrField<Message>();
576           }
577           break;
578       }
579 
580     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
581       switch (field->cpp_string_type()) {
582         case FieldDescriptor::CppStringType::kCord:
583           reinterpret_cast<absl::Cord*>(field_ptr)->~Cord();
584           break;
585         case FieldDescriptor::CppStringType::kView:
586         case FieldDescriptor::CppStringType::kString: {
587           reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy();
588           break;
589         }
590       }
591     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
592           if (!is_prototype()) {
593         Message* message = *reinterpret_cast<Message**>(field_ptr);
594         if (message != nullptr) {
595           delete message;
596         }
597       }
598     }
599   }
600 }
601 
NewImpl(const void * prototype,void * mem,Arena * arena)602 void* DynamicMessage::NewImpl(const void* prototype, void* mem, Arena* arena) {
603   const auto* type_info =
604       static_cast<const DynamicMessage*>(prototype)->type_info_;
605   memset(mem, 0, type_info->class_data.allocation_size());
606   return new (mem) DynamicMessage(type_info, arena);
607 }
608 
DestroyImpl(MessageLite & msg)609 void DynamicMessage::DestroyImpl(MessageLite& msg) {
610   static_cast<DynamicMessage&>(msg).~DynamicMessage();
611 }
612 
CrossLinkPrototypes()613 void DynamicMessage::CrossLinkPrototypes() {
614   // This should only be called on the prototype message.
615   ABSL_CHECK(is_prototype());
616 
617   DynamicMessageFactory* factory = type_info_->factory;
618   const Descriptor* descriptor = type_info_->class_data.descriptor;
619 
620   // Cross-link default messages.
621   for (int i = 0; i < descriptor->field_count(); i++) {
622     const FieldDescriptor* field = descriptor->field(i);
623     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
624         !field->options().weak() && !InRealOneof(field) &&
625         !field->is_repeated()) {
626       void* field_ptr = MutableRaw(i);
627       // For fields with message types, we need to cross-link with the
628       // prototype for the field's type.
629       // For singular fields, the field is just a pointer which should
630       // point to the prototype.
631       *reinterpret_cast<const Message**>(field_ptr) =
632           factory->GetPrototypeNoLock(field->message_type());
633     }
634   }
635 }
636 
GetClassData() const637 const internal::ClassData* DynamicMessage::GetClassData() const {
638   return type_info_->class_data.base();
639 }
640 
641 // ===================================================================
642 
DynamicMessageFactory()643 DynamicMessageFactory::DynamicMessageFactory()
644     : pool_(nullptr), delegate_to_generated_factory_(false) {}
645 
DynamicMessageFactory(const DescriptorPool * pool)646 DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool)
647     : pool_(pool), delegate_to_generated_factory_(false) {}
648 
~DynamicMessageFactory()649 DynamicMessageFactory::~DynamicMessageFactory() {
650   for (auto iter = prototypes_.begin(); iter != prototypes_.end(); ++iter) {
651     delete iter->second;
652   }
653 }
654 
GetPrototype(const Descriptor * type)655 const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) {
656   ABSL_CHECK(type != nullptr);
657   absl::MutexLock lock(&prototypes_mutex_);
658   return GetPrototypeNoLock(type);
659 }
660 
GetPrototypeNoLock(const Descriptor * type)661 const Message* DynamicMessageFactory::GetPrototypeNoLock(
662     const Descriptor* type) {
663   if (delegate_to_generated_factory_ &&
664       type->file()->pool() == DescriptorPool::generated_pool()) {
665     const Message* result = MessageFactory::TryGetGeneratedPrototype(type);
666     if (result != nullptr) return result;
667     // Otherwise, we will create it dynamically so keep going.
668   }
669 
670   const TypeInfo** target = &prototypes_[type];
671   if (*target != nullptr) {
672     // Already exists.
673     return static_cast<const Message*>((*target)->class_data.prototype);
674   }
675 
676   TypeInfo* type_info = new TypeInfo;
677   *target = type_info;
678 
679   type_info->class_data.descriptor = type;
680   type_info->class_data.is_dynamic = true;
681   type_info->pool = (pool_ == nullptr) ? type->file()->pool() : pool_;
682   type_info->factory = this;
683 
684   // We need to construct all the structures passed to Reflection's constructor.
685   // This includes:
686   // - A block of memory that contains space for all the message's fields.
687   // - An array of integers indicating the byte offset of each field within
688   //   this block.
689   // - A big bitfield containing a bit for each field indicating whether
690   //   or not that field is set.
691   int real_oneof_count = type->real_oneof_decl_count();
692 
693   // Compute size and offsets.
694   uint32_t* offsets = new uint32_t[type->field_count() + real_oneof_count];
695   type_info->offsets.reset(offsets);
696 
697   // Decide all field offsets by packing in order.
698   // We place the DynamicMessage object itself at the beginning of the allocated
699   // space.
700   int size = sizeof(DynamicMessage);
701   size = AlignOffset(size);
702 
703   // Next the has_bits, which is an array of uint32s.
704   type_info->has_bits_offset = -1;
705   int max_hasbit = 0;
706   for (int i = 0; i < type->field_count(); i++) {
707     if (internal::cpp::HasHasbit(type->field(i))) {
708       if (type_info->has_bits_offset == -1) {
709         // At least one field in the message requires a hasbit, so allocate
710         // hasbits.
711         type_info->has_bits_offset = size;
712         uint32_t* has_bits_indices = new uint32_t[type->field_count()];
713         for (int j = 0; j < type->field_count(); j++) {
714           // Initialize to -1, fields that need a hasbit will overwrite.
715           has_bits_indices[j] = static_cast<uint32_t>(-1);
716         }
717         type_info->has_bits_indices.reset(has_bits_indices);
718       }
719       type_info->has_bits_indices[i] = max_hasbit++;
720     }
721   }
722 
723   if (max_hasbit > 0) {
724     int has_bits_array_size = DivideRoundingUp(max_hasbit, bitsizeof(uint32_t));
725     size += has_bits_array_size * sizeof(uint32_t);
726     size = AlignOffset(size);
727   }
728 
729   // The oneof_case, if any. It is an array of uint32s.
730   if (real_oneof_count > 0) {
731     type_info->oneof_case_offset = size;
732     size += real_oneof_count * sizeof(uint32_t);
733     size = AlignOffset(size);
734   }
735 
736   // The ExtensionSet, if any.
737   if (type->extension_range_count() > 0) {
738     type_info->extensions_offset = size;
739     size += sizeof(ExtensionSet);
740     size = AlignOffset(size);
741   } else {
742     // No extensions.
743     type_info->extensions_offset = -1;
744   }
745 
746   // All the fields.
747   //
748   // TODO:  Optimize the order of fields to minimize padding.
749   for (int i = 0; i < type->field_count(); i++) {
750     // Make sure field is aligned to avoid bus errors.
751     // Oneof fields do not use any space.
752     if (!InRealOneof(type->field(i))) {
753       int field_size = FieldSpaceUsed(type->field(i));
754       size = AlignTo(size, std::min(kSafeAlignment, field_size));
755       offsets[i] = size;
756       size += field_size;
757     }
758   }
759 
760   // The oneofs.
761   for (int i = 0; i < type->real_oneof_decl_count(); i++) {
762     size = AlignTo(size, kSafeAlignment);
763     offsets[type->field_count() + i] = size;
764     size += kMaxOneofUnionSize;
765   }
766 
767   type_info->weak_field_map_offset = -1;
768 
769   type_info->class_data.message_creator =
770       internal::MessageCreator(DynamicMessage::NewImpl, size, kSafeAlignment);
771 
772   // Construct the reflection object.
773 
774   // Compute the size of default oneof instance and offsets of default
775   // oneof fields.
776   for (int i = 0; i < type->real_oneof_decl_count(); i++) {
777     for (int j = 0; j < type->real_oneof_decl(i)->field_count(); j++) {
778       const FieldDescriptor* field = type->real_oneof_decl(i)->field(j);
779       // oneof fields are not accessed through offsets, but we still have the
780       // entry from a legacy implementation. This should be removed at some
781       // point.
782       // Mark the field to prevent unintentional access through reflection.
783       // Don't use the top bit because that is for unused fields.
784       offsets[field->index()] = internal::kInvalidFieldOffsetTag;
785     }
786   }
787 
788   // Allocate the prototype fields.
789   void* base = operator new(size);
790   memset(base, 0, size);
791 
792   // We have already locked the factory so we should not lock in the constructor
793   // of dynamic message to avoid dead lock.
794   DynamicMessage* prototype = new (base) DynamicMessage(type_info, false);
795 
796   internal::ReflectionSchema schema = {
797       static_cast<const Message*>(type_info->class_data.prototype),
798       type_info->offsets.get(),
799       type_info->has_bits_indices.get(),
800       type_info->has_bits_offset,
801       PROTOBUF_FIELD_OFFSET(DynamicMessage, _internal_metadata_),
802       type_info->extensions_offset,
803       type_info->oneof_case_offset,
804       static_cast<int>(type_info->class_data.allocation_size()),
805       type_info->weak_field_map_offset,
806       nullptr,  // inlined_string_indices_
807       0,        // inlined_string_donated_offset_
808       -1,       // split_offset_
809       -1,       // sizeof_split_
810   };
811 
812   type_info->class_data.reflection = new Reflection(
813       type_info->class_data.descriptor, schema, type_info->pool, this);
814 
815   // Cross link prototypes.
816   prototype->CrossLinkPrototypes();
817 
818   return prototype;
819 }
820 
821 }  // namespace protobuf
822 }  // namespace google
823 
824 #include "google/protobuf/port_undef.inc"  // NOLINT
825