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