• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // DynamicMessage is implemented by constructing a data structure which
36 // has roughly the same memory layout as a generated message would have.
37 // Then, we use Reflection to implement our reflection interface.  All
38 // the other operations we need to implement (e.g.  parsing, copying,
39 // etc.) are already implemented in terms of Reflection, so the rest is
40 // easy.
41 //
42 // The up side of this strategy is that it's very efficient.  We don't
43 // need to use hash_maps or generic representations of fields.  The
44 // down side is that this is a low-level memory management hack which
45 // can be tricky to get right.
46 //
47 // As mentioned in the header, we only expose a DynamicMessageFactory
48 // publicly, not the DynamicMessage class itself.  This is because
49 // GenericMessageReflection wants to have a pointer to a "default"
50 // copy of the class, with all fields initialized to their default
51 // values.  We only want to construct one of these per message type,
52 // so DynamicMessageFactory stores a cache of default messages for
53 // each type it sees (each unique Descriptor pointer).  The code
54 // refers to the "default" copy of the class as the "prototype".
55 //
56 // Note on memory allocation:  This module often calls "operator new()"
57 // to allocate untyped memory, rather than calling something like
58 // "new uint8[]".  This is because "operator new()" means "Give me some
59 // space which I can use as I please." while "new uint8[]" means "Give
60 // me an array of 8-bit integers.".  In practice, the later may return
61 // a pointer that is not aligned correctly for general use.  I believe
62 // Item 8 of "More Effective C++" discusses this in more detail, though
63 // I don't have the book on me right now so I'm not sure.
64 
65 #include <algorithm>
66 #include <memory>
67 #include <unordered_map>
68 
69 #include <google/protobuf/stubs/hash.h>
70 
71 #include <google/protobuf/descriptor.pb.h>
72 #include <google/protobuf/descriptor.h>
73 #include <google/protobuf/dynamic_message.h>
74 #include <google/protobuf/generated_message_reflection.h>
75 #include <google/protobuf/generated_message_util.h>
76 #include <google/protobuf/arenastring.h>
77 #include <google/protobuf/extension_set.h>
78 #include <google/protobuf/map_field.h>
79 #include <google/protobuf/map_field_inl.h>
80 #include <google/protobuf/map_type_handler.h>
81 #include <google/protobuf/reflection_ops.h>
82 #include <google/protobuf/repeated_field.h>
83 #include <google/protobuf/wire_format.h>
84 
85 namespace google {
86 namespace protobuf {
87 
88 using internal::DynamicMapField;
89 using internal::ExtensionSet;
90 using internal::InternalMetadataWithArena;
91 using internal::MapField;
92 
93 
94 using internal::ArenaStringPtr;
95 
96 // ===================================================================
97 // Some helper tables and functions...
98 
99 namespace {
100 
IsMapFieldInApi(const FieldDescriptor * field)101 bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); }
102 
103 // Compute the byte size of the in-memory representation of the field.
FieldSpaceUsed(const FieldDescriptor * field)104 int FieldSpaceUsed(const FieldDescriptor* field) {
105   typedef FieldDescriptor FD;  // avoid line wrapping
106   if (field->label() == FD::LABEL_REPEATED) {
107     switch (field->cpp_type()) {
108       case FD::CPPTYPE_INT32:
109         return sizeof(RepeatedField<int32>);
110       case FD::CPPTYPE_INT64:
111         return sizeof(RepeatedField<int64>);
112       case FD::CPPTYPE_UINT32:
113         return sizeof(RepeatedField<uint32>);
114       case FD::CPPTYPE_UINT64:
115         return sizeof(RepeatedField<uint64>);
116       case FD::CPPTYPE_DOUBLE:
117         return sizeof(RepeatedField<double>);
118       case FD::CPPTYPE_FLOAT:
119         return sizeof(RepeatedField<float>);
120       case FD::CPPTYPE_BOOL:
121         return sizeof(RepeatedField<bool>);
122       case FD::CPPTYPE_ENUM:
123         return sizeof(RepeatedField<int>);
124       case FD::CPPTYPE_MESSAGE:
125         if (IsMapFieldInApi(field)) {
126           return sizeof(DynamicMapField);
127         } else {
128           return sizeof(RepeatedPtrField<Message>);
129         }
130 
131       case FD::CPPTYPE_STRING:
132         switch (field->options().ctype()) {
133           default:  // TODO(kenton):  Support other string reps.
134           case FieldOptions::STRING:
135             return sizeof(RepeatedPtrField<std::string>);
136         }
137         break;
138     }
139   } else {
140     switch (field->cpp_type()) {
141       case FD::CPPTYPE_INT32:
142         return sizeof(int32);
143       case FD::CPPTYPE_INT64:
144         return sizeof(int64);
145       case FD::CPPTYPE_UINT32:
146         return sizeof(uint32);
147       case FD::CPPTYPE_UINT64:
148         return sizeof(uint64);
149       case FD::CPPTYPE_DOUBLE:
150         return sizeof(double);
151       case FD::CPPTYPE_FLOAT:
152         return sizeof(float);
153       case FD::CPPTYPE_BOOL:
154         return sizeof(bool);
155       case FD::CPPTYPE_ENUM:
156         return sizeof(int);
157 
158       case FD::CPPTYPE_MESSAGE:
159         return sizeof(Message*);
160 
161       case FD::CPPTYPE_STRING:
162         switch (field->options().ctype()) {
163           default:  // TODO(kenton):  Support other string reps.
164           case FieldOptions::STRING:
165             return sizeof(ArenaStringPtr);
166         }
167         break;
168     }
169   }
170 
171   GOOGLE_LOG(DFATAL) << "Can't get here.";
172   return 0;
173 }
174 
175 // Compute the byte size of in-memory representation of the oneof fields
176 // in default oneof instance.
OneofFieldSpaceUsed(const FieldDescriptor * field)177 int OneofFieldSpaceUsed(const FieldDescriptor* field) {
178   typedef FieldDescriptor FD;  // avoid line wrapping
179   switch (field->cpp_type()) {
180     case FD::CPPTYPE_INT32:
181       return sizeof(int32);
182     case FD::CPPTYPE_INT64:
183       return sizeof(int64);
184     case FD::CPPTYPE_UINT32:
185       return sizeof(uint32);
186     case FD::CPPTYPE_UINT64:
187       return sizeof(uint64);
188     case FD::CPPTYPE_DOUBLE:
189       return sizeof(double);
190     case FD::CPPTYPE_FLOAT:
191       return sizeof(float);
192     case FD::CPPTYPE_BOOL:
193       return sizeof(bool);
194     case FD::CPPTYPE_ENUM:
195       return sizeof(int);
196 
197     case FD::CPPTYPE_MESSAGE:
198       return sizeof(Message*);
199 
200     case FD::CPPTYPE_STRING:
201       switch (field->options().ctype()) {
202         default:
203         case FieldOptions::STRING:
204           return sizeof(ArenaStringPtr);
205       }
206       break;
207   }
208 
209   GOOGLE_LOG(DFATAL) << "Can't get here.";
210   return 0;
211 }
212 
DivideRoundingUp(int i,int j)213 inline int DivideRoundingUp(int i, int j) { return (i + (j - 1)) / j; }
214 
215 static const int kSafeAlignment = sizeof(uint64);
216 static const int kMaxOneofUnionSize = sizeof(uint64);
217 
AlignTo(int offset,int alignment)218 inline int AlignTo(int offset, int alignment) {
219   return DivideRoundingUp(offset, alignment) * alignment;
220 }
221 
222 // Rounds the given byte offset up to the next offset aligned such that any
223 // type may be stored at it.
AlignOffset(int offset)224 inline int AlignOffset(int offset) { return AlignTo(offset, kSafeAlignment); }
225 
226 #define bitsizeof(T) (sizeof(T) * 8)
227 
228 }  // namespace
229 
230 // ===================================================================
231 
232 class DynamicMessage : public Message {
233  public:
234   struct TypeInfo {
235     int size;
236     int has_bits_offset;
237     int oneof_case_offset;
238     int internal_metadata_offset;
239     int extensions_offset;
240 
241     // Not owned by the TypeInfo.
242     DynamicMessageFactory* factory;  // The factory that created this object.
243     const DescriptorPool* pool;      // The factory's DescriptorPool.
244     const Descriptor* type;          // Type of this DynamicMessage.
245 
246     // Warning:  The order in which the following pointers are defined is
247     //   important (the prototype must be deleted *before* the offsets).
248     std::unique_ptr<uint32[]> offsets;
249     std::unique_ptr<uint32[]> has_bits_indices;
250     std::unique_ptr<const Reflection> reflection;
251     // Don't use a unique_ptr to hold the prototype: the destructor for
252     // DynamicMessage needs to know whether it is the prototype, and does so by
253     // looking back at this field. This would assume details about the
254     // implementation of unique_ptr.
255     const DynamicMessage* prototype;
256     int weak_field_map_offset;  // The offset for the weak_field_map;
257 
TypeInfogoogle::protobuf::DynamicMessage::TypeInfo258     TypeInfo() : prototype(NULL) {}
259 
~TypeInfogoogle::protobuf::DynamicMessage::TypeInfo260     ~TypeInfo() { delete prototype; }
261   };
262 
263   DynamicMessage(const TypeInfo* type_info);
264 
265   // This should only be used by GetPrototypeNoLock() to avoid dead lock.
266   DynamicMessage(TypeInfo* type_info, bool lock_factory);
267 
268   ~DynamicMessage();
269 
270   // Called on the prototype after construction to initialize message fields.
271   void CrossLinkPrototypes();
272 
273   // implements Message ----------------------------------------------
274 
275   Message* New() const override;
276   Message* New(Arena* arena) const override;
GetArena() const277   Arena* GetArena() const override { return arena_; }
278 
279   int GetCachedSize() const override;
280   void SetCachedSize(int size) const override;
281 
282   Metadata GetMetadata() const override;
283 
284   // We actually allocate more memory than sizeof(*this) when this
285   // class's memory is allocated via the global operator new. Thus, we need to
286   // manually call the global operator delete. Calling the destructor is taken
287   // care of for us. This makes DynamicMessage compatible with -fsized-delete.
288   // It doesn't work for MSVC though.
289 #ifndef _MSC_VER
operator delete(void * ptr)290   static void operator delete(void* ptr) { ::operator delete(ptr); }
291 #endif  // !_MSC_VER
292 
293  private:
294   DynamicMessage(const TypeInfo* type_info, Arena* arena);
295 
296   void SharedCtor(bool lock_factory);
297 
is_prototype() const298   inline bool is_prototype() const {
299     return type_info_->prototype == this ||
300            // If type_info_->prototype is NULL, then we must be constructing
301            // the prototype now, which means we must be the prototype.
302            type_info_->prototype == NULL;
303   }
304 
OffsetToPointer(int offset)305   inline void* OffsetToPointer(int offset) {
306     return reinterpret_cast<uint8*>(this) + offset;
307   }
OffsetToPointer(int offset) const308   inline const void* OffsetToPointer(int offset) const {
309     return reinterpret_cast<const uint8*>(this) + offset;
310   }
311 
312   const TypeInfo* type_info_;
313   Arena* const arena_;
314   mutable std::atomic<int> cached_byte_size_;
315   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
316 };
317 
DynamicMessage(const TypeInfo * type_info)318 DynamicMessage::DynamicMessage(const TypeInfo* type_info)
319     : type_info_(type_info), arena_(NULL), cached_byte_size_(0) {
320   SharedCtor(true);
321 }
322 
DynamicMessage(const TypeInfo * type_info,Arena * arena)323 DynamicMessage::DynamicMessage(const TypeInfo* type_info, Arena* arena)
324     : type_info_(type_info), arena_(arena), cached_byte_size_(0) {
325   SharedCtor(true);
326 }
327 
DynamicMessage(TypeInfo * type_info,bool lock_factory)328 DynamicMessage::DynamicMessage(TypeInfo* type_info, bool lock_factory)
329     : type_info_(type_info), arena_(NULL), cached_byte_size_(0) {
330   // The prototype in type_info has to be set before creating the prototype
331   // instance on memory. e.g., message Foo { map<int32, Foo> a = 1; }. When
332   // creating prototype for Foo, prototype of the map entry will also be
333   // created, which needs the address of the prototype of Foo (the value in
334   // map). To break the cyclic dependency, we have to assign the address of
335   // prototype into type_info first.
336   type_info->prototype = this;
337   SharedCtor(lock_factory);
338 }
339 
SharedCtor(bool lock_factory)340 void DynamicMessage::SharedCtor(bool lock_factory) {
341   // We need to call constructors for various fields manually and set
342   // default values where appropriate.  We use placement new to call
343   // constructors.  If you haven't heard of placement new, I suggest Googling
344   // it now.  We use placement new even for primitive types that don't have
345   // constructors for consistency.  (In theory, placement new should be used
346   // any time you are trying to convert untyped memory to typed memory, though
347   // in practice that's not strictly necessary for types that don't have a
348   // constructor.)
349 
350   const Descriptor* descriptor = type_info_->type;
351   // Initialize oneof cases.
352   for (int i = 0; i < descriptor->oneof_decl_count(); ++i) {
353     new (OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i))
354         uint32(0);
355   }
356 
357   new (OffsetToPointer(type_info_->internal_metadata_offset))
358       InternalMetadataWithArena(arena_);
359 
360   if (type_info_->extensions_offset != -1) {
361     new (OffsetToPointer(type_info_->extensions_offset)) ExtensionSet(arena_);
362   }
363   for (int i = 0; i < descriptor->field_count(); i++) {
364     const FieldDescriptor* field = descriptor->field(i);
365     void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
366     if (field->containing_oneof()) {
367       continue;
368     }
369     switch (field->cpp_type()) {
370 #define HANDLE_TYPE(CPPTYPE, TYPE)                         \
371   case FieldDescriptor::CPPTYPE_##CPPTYPE:                 \
372     if (!field->is_repeated()) {                           \
373       new (field_ptr) TYPE(field->default_value_##TYPE()); \
374     } else {                                               \
375       new (field_ptr) RepeatedField<TYPE>(arena_);         \
376     }                                                      \
377     break;
378 
379       HANDLE_TYPE(INT32, int32);
380       HANDLE_TYPE(INT64, int64);
381       HANDLE_TYPE(UINT32, uint32);
382       HANDLE_TYPE(UINT64, uint64);
383       HANDLE_TYPE(DOUBLE, double);
384       HANDLE_TYPE(FLOAT, float);
385       HANDLE_TYPE(BOOL, bool);
386 #undef HANDLE_TYPE
387 
388       case FieldDescriptor::CPPTYPE_ENUM:
389         if (!field->is_repeated()) {
390           new (field_ptr) int(field->default_value_enum()->number());
391         } else {
392           new (field_ptr) RepeatedField<int>(arena_);
393         }
394         break;
395 
396       case FieldDescriptor::CPPTYPE_STRING:
397         switch (field->options().ctype()) {
398           default:  // TODO(kenton):  Support other string reps.
399           case FieldOptions::STRING:
400             if (!field->is_repeated()) {
401               const std::string* default_value;
402               if (is_prototype()) {
403                 default_value = &field->default_value_string();
404               } else {
405                 default_value = &(reinterpret_cast<const ArenaStringPtr*>(
406                                       type_info_->prototype->OffsetToPointer(
407                                           type_info_->offsets[i]))
408                                       ->Get());
409               }
410               ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr();
411               asp->UnsafeSetDefault(default_value);
412             } else {
413               new (field_ptr) RepeatedPtrField<std::string>(arena_);
414             }
415             break;
416         }
417         break;
418 
419       case FieldDescriptor::CPPTYPE_MESSAGE: {
420         if (!field->is_repeated()) {
421           new (field_ptr) Message*(NULL);
422         } else {
423           if (IsMapFieldInApi(field)) {
424             // We need to lock in most cases to avoid data racing. Only not lock
425             // when the constructor is called inside GetPrototype(), in which
426             // case we have already locked the factory.
427             if (lock_factory) {
428               if (arena_ != NULL) {
429                 new (field_ptr) DynamicMapField(
430                     type_info_->factory->GetPrototype(field->message_type()),
431                     arena_);
432               } else {
433                 new (field_ptr) DynamicMapField(
434                     type_info_->factory->GetPrototype(field->message_type()));
435               }
436             } else {
437               if (arena_ != NULL) {
438                 new (field_ptr)
439                     DynamicMapField(type_info_->factory->GetPrototypeNoLock(
440                                         field->message_type()),
441                                     arena_);
442               } else {
443                 new (field_ptr)
444                     DynamicMapField(type_info_->factory->GetPrototypeNoLock(
445                         field->message_type()));
446               }
447             }
448           } else {
449             new (field_ptr) RepeatedPtrField<Message>(arena_);
450           }
451         }
452         break;
453       }
454     }
455   }
456 }
457 
~DynamicMessage()458 DynamicMessage::~DynamicMessage() {
459   const Descriptor* descriptor = type_info_->type;
460 
461   reinterpret_cast<InternalMetadataWithArena*>(
462       OffsetToPointer(type_info_->internal_metadata_offset))
463       ->~InternalMetadataWithArena();
464 
465   if (type_info_->extensions_offset != -1) {
466     reinterpret_cast<ExtensionSet*>(
467         OffsetToPointer(type_info_->extensions_offset))
468         ->~ExtensionSet();
469   }
470 
471   // We need to manually run the destructors for repeated fields and strings,
472   // just as we ran their constructors in the DynamicMessage constructor.
473   // We also need to manually delete oneof fields if it is set and is string
474   // or message.
475   // Additionally, if any singular embedded messages have been allocated, we
476   // need to delete them, UNLESS we are the prototype message of this type,
477   // in which case any embedded messages are other prototypes and shouldn't
478   // be touched.
479   for (int i = 0; i < descriptor->field_count(); i++) {
480     const FieldDescriptor* field = descriptor->field(i);
481     if (field->containing_oneof()) {
482       void* field_ptr =
483           OffsetToPointer(type_info_->oneof_case_offset +
484                           sizeof(uint32) * field->containing_oneof()->index());
485       if (*(reinterpret_cast<const uint32*>(field_ptr)) == field->number()) {
486         field_ptr = OffsetToPointer(
487             type_info_->offsets[descriptor->field_count() +
488                                 field->containing_oneof()->index()]);
489         if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
490           switch (field->options().ctype()) {
491             default:
492             case FieldOptions::STRING: {
493               const std::string* default_value =
494                   &(reinterpret_cast<const ArenaStringPtr*>(
495                         reinterpret_cast<const uint8*>(type_info_->prototype) +
496                         type_info_->offsets[i])
497                         ->Get());
498               reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(
499                   default_value, NULL);
500               break;
501             }
502           }
503         } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
504             delete *reinterpret_cast<Message**>(field_ptr);
505         }
506       }
507       continue;
508     }
509     void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
510 
511     if (field->is_repeated()) {
512       switch (field->cpp_type()) {
513 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                  \
514   case FieldDescriptor::CPPTYPE_##UPPERCASE:               \
515     reinterpret_cast<RepeatedField<LOWERCASE>*>(field_ptr) \
516         ->~RepeatedField<LOWERCASE>();                     \
517     break
518 
519         HANDLE_TYPE(INT32, int32);
520         HANDLE_TYPE(INT64, int64);
521         HANDLE_TYPE(UINT32, uint32);
522         HANDLE_TYPE(UINT64, uint64);
523         HANDLE_TYPE(DOUBLE, double);
524         HANDLE_TYPE(FLOAT, float);
525         HANDLE_TYPE(BOOL, bool);
526         HANDLE_TYPE(ENUM, int);
527 #undef HANDLE_TYPE
528 
529         case FieldDescriptor::CPPTYPE_STRING:
530           switch (field->options().ctype()) {
531             default:  // TODO(kenton):  Support other string reps.
532             case FieldOptions::STRING:
533               reinterpret_cast<RepeatedPtrField<std::string>*>(field_ptr)
534                   ->~RepeatedPtrField<std::string>();
535               break;
536           }
537           break;
538 
539         case FieldDescriptor::CPPTYPE_MESSAGE:
540           if (IsMapFieldInApi(field)) {
541             reinterpret_cast<DynamicMapField*>(field_ptr)->~DynamicMapField();
542           } else {
543             reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr)
544                 ->~RepeatedPtrField<Message>();
545           }
546           break;
547       }
548 
549     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
550       switch (field->options().ctype()) {
551         default:  // TODO(kenton):  Support other string reps.
552         case FieldOptions::STRING: {
553           const std::string* default_value =
554               &(reinterpret_cast<const ArenaStringPtr*>(
555                     type_info_->prototype->OffsetToPointer(
556                         type_info_->offsets[i]))
557                     ->Get());
558           reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(default_value,
559                                                                 NULL);
560           break;
561         }
562       }
563     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
564           if (!is_prototype()) {
565         Message* message = *reinterpret_cast<Message**>(field_ptr);
566         if (message != NULL) {
567           delete message;
568         }
569       }
570     }
571   }
572 }
573 
CrossLinkPrototypes()574 void DynamicMessage::CrossLinkPrototypes() {
575   // This should only be called on the prototype message.
576   GOOGLE_CHECK(is_prototype());
577 
578   DynamicMessageFactory* factory = type_info_->factory;
579   const Descriptor* descriptor = type_info_->type;
580 
581   // Cross-link default messages.
582   for (int i = 0; i < descriptor->field_count(); i++) {
583     const FieldDescriptor* field = descriptor->field(i);
584     void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
585     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
586         !field->is_repeated()) {
587       // For fields with message types, we need to cross-link with the
588       // prototype for the field's type.
589       // For singular fields, the field is just a pointer which should
590       // point to the prototype.
591       *reinterpret_cast<const Message**>(field_ptr) =
592           factory->GetPrototypeNoLock(field->message_type());
593     }
594   }
595 }
596 
New() const597 Message* DynamicMessage::New() const { return New(NULL); }
598 
New(Arena * arena) const599 Message* DynamicMessage::New(Arena* arena) const {
600   if (arena != NULL) {
601     void* new_base = Arena::CreateArray<char>(arena, type_info_->size);
602     memset(new_base, 0, type_info_->size);
603     return new (new_base) DynamicMessage(type_info_, arena);
604   } else {
605     void* new_base = operator new(type_info_->size);
606     memset(new_base, 0, type_info_->size);
607     return new (new_base) DynamicMessage(type_info_);
608   }
609 }
610 
GetCachedSize() const611 int DynamicMessage::GetCachedSize() const {
612   return cached_byte_size_.load(std::memory_order_relaxed);
613 }
614 
SetCachedSize(int size) const615 void DynamicMessage::SetCachedSize(int size) const {
616   cached_byte_size_.store(size, std::memory_order_relaxed);
617 }
618 
GetMetadata() const619 Metadata DynamicMessage::GetMetadata() const {
620   Metadata metadata;
621   metadata.descriptor = type_info_->type;
622   metadata.reflection = type_info_->reflection.get();
623   return metadata;
624 }
625 
626 // ===================================================================
627 
628 struct DynamicMessageFactory::PrototypeMap {
629   typedef std::unordered_map<const Descriptor*, const DynamicMessage::TypeInfo*>
630       Map;
631   Map map_;
632 };
633 
DynamicMessageFactory()634 DynamicMessageFactory::DynamicMessageFactory()
635     : pool_(NULL),
636       delegate_to_generated_factory_(false),
637       prototypes_(new PrototypeMap) {}
638 
DynamicMessageFactory(const DescriptorPool * pool)639 DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool)
640     : pool_(pool),
641       delegate_to_generated_factory_(false),
642       prototypes_(new PrototypeMap) {}
643 
~DynamicMessageFactory()644 DynamicMessageFactory::~DynamicMessageFactory() {
645   for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin();
646        iter != prototypes_->map_.end(); ++iter) {
647     DeleteDefaultOneofInstance(iter->second->type, iter->second->offsets.get(),
648                                iter->second->prototype);
649     delete iter->second;
650   }
651 }
652 
GetPrototype(const Descriptor * type)653 const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) {
654   MutexLock lock(&prototypes_mutex_);
655   return GetPrototypeNoLock(type);
656 }
657 
GetPrototypeNoLock(const Descriptor * type)658 const Message* DynamicMessageFactory::GetPrototypeNoLock(
659     const Descriptor* type) {
660   if (delegate_to_generated_factory_ &&
661       type->file()->pool() == DescriptorPool::generated_pool()) {
662     return MessageFactory::generated_factory()->GetPrototype(type);
663   }
664 
665   const DynamicMessage::TypeInfo** target = &prototypes_->map_[type];
666   if (*target != NULL) {
667     // Already exists.
668     return (*target)->prototype;
669   }
670 
671   DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo;
672   *target = type_info;
673 
674   type_info->type = type;
675   type_info->pool = (pool_ == NULL) ? type->file()->pool() : pool_;
676   type_info->factory = this;
677 
678   // We need to construct all the structures passed to Reflection's constructor.
679   // This includes:
680   // - A block of memory that contains space for all the message's fields.
681   // - An array of integers indicating the byte offset of each field within
682   //   this block.
683   // - A big bitfield containing a bit for each field indicating whether
684   //   or not that field is set.
685 
686   // Compute size and offsets.
687   uint32* offsets = new uint32[type->field_count() + type->oneof_decl_count()];
688   type_info->offsets.reset(offsets);
689 
690   // Decide all field offsets by packing in order.
691   // We place the DynamicMessage object itself at the beginning of the allocated
692   // space.
693   int size = sizeof(DynamicMessage);
694   size = AlignOffset(size);
695 
696   // Next the has_bits, which is an array of uint32s.
697   if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
698     type_info->has_bits_offset = -1;
699   } else {
700     type_info->has_bits_offset = size;
701     int has_bits_array_size =
702         DivideRoundingUp(type->field_count(), bitsizeof(uint32));
703     size += has_bits_array_size * sizeof(uint32);
704     size = AlignOffset(size);
705 
706     uint32* has_bits_indices = new uint32[type->field_count()];
707     for (int i = 0; i < type->field_count(); i++) {
708       has_bits_indices[i] = i;
709     }
710     type_info->has_bits_indices.reset(has_bits_indices);
711   }
712 
713   // The oneof_case, if any. It is an array of uint32s.
714   if (type->oneof_decl_count() > 0) {
715     type_info->oneof_case_offset = size;
716     size += type->oneof_decl_count() * sizeof(uint32);
717     size = AlignOffset(size);
718   }
719 
720   // The ExtensionSet, if any.
721   if (type->extension_range_count() > 0) {
722     type_info->extensions_offset = size;
723     size += sizeof(ExtensionSet);
724     size = AlignOffset(size);
725   } else {
726     // No extensions.
727     type_info->extensions_offset = -1;
728   }
729 
730   // All the fields.
731   //
732   // TODO(b/31226269):  Optimize the order of fields to minimize padding.
733   int num_weak_fields = 0;
734   for (int i = 0; i < type->field_count(); i++) {
735     // Make sure field is aligned to avoid bus errors.
736     // Oneof fields do not use any space.
737     if (!type->field(i)->containing_oneof()) {
738       int field_size = FieldSpaceUsed(type->field(i));
739       size = AlignTo(size, std::min(kSafeAlignment, field_size));
740       offsets[i] = size;
741       size += field_size;
742     }
743   }
744 
745   // The oneofs.
746   for (int i = 0; i < type->oneof_decl_count(); i++) {
747     size = AlignTo(size, kSafeAlignment);
748     offsets[type->field_count() + i] = size;
749     size += kMaxOneofUnionSize;
750   }
751 
752   // Add the InternalMetadataWithArena to the end.
753   size = AlignOffset(size);
754   type_info->internal_metadata_offset = size;
755   size += sizeof(InternalMetadataWithArena);
756 
757   type_info->weak_field_map_offset = -1;
758 
759   // Align the final size to make sure no clever allocators think that
760   // alignment is not necessary.
761   type_info->size = size;
762 
763   // Construct the reflection object.
764 
765   if (type->oneof_decl_count() > 0) {
766     // Compute the size of default oneof instance and offsets of default
767     // oneof fields.
768     for (int i = 0; i < type->oneof_decl_count(); i++) {
769       for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
770         const FieldDescriptor* field = type->oneof_decl(i)->field(j);
771         int field_size = OneofFieldSpaceUsed(field);
772         size = AlignTo(size, std::min(kSafeAlignment, field_size));
773         offsets[field->index()] = size;
774         size += field_size;
775       }
776     }
777   }
778   size = AlignOffset(size);
779   // Allocate the prototype + oneof fields.
780   void* base = operator new(size);
781   memset(base, 0, size);
782 
783   // We have already locked the factory so we should not lock in the constructor
784   // of dynamic message to avoid dead lock.
785   DynamicMessage* prototype = new (base) DynamicMessage(type_info, false);
786 
787   if (type->oneof_decl_count() > 0 || num_weak_fields > 0) {
788     // Construct default oneof instance.
789     ConstructDefaultOneofInstance(type_info->type, type_info->offsets.get(),
790                                   prototype);
791   }
792 
793   internal::ReflectionSchema schema = {type_info->prototype,
794                                        type_info->offsets.get(),
795                                        type_info->has_bits_indices.get(),
796                                        type_info->has_bits_offset,
797                                        type_info->internal_metadata_offset,
798                                        type_info->extensions_offset,
799                                        type_info->oneof_case_offset,
800                                        type_info->size,
801                                        type_info->weak_field_map_offset};
802 
803   type_info->reflection.reset(
804       new Reflection(type_info->type, schema, type_info->pool, this));
805 
806   // Cross link prototypes.
807   prototype->CrossLinkPrototypes();
808 
809   return prototype;
810 }
811 
ConstructDefaultOneofInstance(const Descriptor * type,const uint32 offsets[],void * default_oneof_or_weak_instance)812 void DynamicMessageFactory::ConstructDefaultOneofInstance(
813     const Descriptor* type, const uint32 offsets[],
814     void* default_oneof_or_weak_instance) {
815   for (int i = 0; i < type->oneof_decl_count(); i++) {
816     for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
817       const FieldDescriptor* field = type->oneof_decl(i)->field(j);
818       void* field_ptr =
819           reinterpret_cast<uint8*>(default_oneof_or_weak_instance) +
820           offsets[field->index()];
821       switch (field->cpp_type()) {
822 #define HANDLE_TYPE(CPPTYPE, TYPE)                       \
823   case FieldDescriptor::CPPTYPE_##CPPTYPE:               \
824     new (field_ptr) TYPE(field->default_value_##TYPE()); \
825     break;
826 
827         HANDLE_TYPE(INT32, int32);
828         HANDLE_TYPE(INT64, int64);
829         HANDLE_TYPE(UINT32, uint32);
830         HANDLE_TYPE(UINT64, uint64);
831         HANDLE_TYPE(DOUBLE, double);
832         HANDLE_TYPE(FLOAT, float);
833         HANDLE_TYPE(BOOL, bool);
834 #undef HANDLE_TYPE
835 
836         case FieldDescriptor::CPPTYPE_ENUM:
837           new (field_ptr) int(field->default_value_enum()->number());
838           break;
839         case FieldDescriptor::CPPTYPE_STRING:
840           switch (field->options().ctype()) {
841             default:
842             case FieldOptions::STRING:
843               ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr();
844               asp->UnsafeSetDefault(&field->default_value_string());
845               break;
846           }
847           break;
848 
849         case FieldDescriptor::CPPTYPE_MESSAGE: {
850           new (field_ptr) Message*(NULL);
851           break;
852         }
853       }
854     }
855   }
856 }
857 
DeleteDefaultOneofInstance(const Descriptor * type,const uint32 offsets[],const void * default_oneof_instance)858 void DynamicMessageFactory::DeleteDefaultOneofInstance(
859     const Descriptor* type, const uint32 offsets[],
860     const void* default_oneof_instance) {
861   for (int i = 0; i < type->oneof_decl_count(); i++) {
862     for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
863       const FieldDescriptor* field = type->oneof_decl(i)->field(j);
864       if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
865         switch (field->options().ctype()) {
866           default:
867           case FieldOptions::STRING:
868             break;
869         }
870       }
871     }
872   }
873 }
874 
875 }  // namespace protobuf
876 }  // namespace google
877