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