LCOV - code coverage report
Current view: top level - toolkit/components/protobuf/src/google/protobuf - dynamic_message.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 303 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13