| Index: third_party/protobuf/src/google/protobuf/dynamic_message.cc | 
| diff --git a/third_party/protobuf/src/google/protobuf/dynamic_message.cc b/third_party/protobuf/src/google/protobuf/dynamic_message.cc | 
| index 09bec54363aa2eba3004ea0ea6b6e11f67b3d780..bb4004769d4d5e9b3a333cbb187fe8f71acc8e06 100644 | 
| --- a/third_party/protobuf/src/google/protobuf/dynamic_message.cc | 
| +++ b/third_party/protobuf/src/google/protobuf/dynamic_message.cc | 
| @@ -1,6 +1,6 @@ | 
| // Protocol Buffers - Google's data interchange format | 
| // Copyright 2008 Google Inc.  All rights reserved. | 
| -// http://code.google.com/p/protobuf/ | 
| +// https://developers.google.com/protocol-buffers/ | 
| // | 
| // Redistribution and use in source and binary forms, with or without | 
| // modification, are permitted provided that the following conditions are | 
| @@ -64,18 +64,27 @@ | 
|  | 
| #include <algorithm> | 
| #include <google/protobuf/stubs/hash.h> | 
| +#include <memory> | 
| +#ifndef _SHARED_PTR_H | 
| +#include <google/protobuf/stubs/shared_ptr.h> | 
| +#endif | 
|  | 
| #include <google/protobuf/stubs/common.h> | 
| +#include <google/protobuf/stubs/scoped_ptr.h> | 
|  | 
| #include <google/protobuf/dynamic_message.h> | 
| #include <google/protobuf/descriptor.h> | 
| #include <google/protobuf/descriptor.pb.h> | 
| #include <google/protobuf/generated_message_util.h> | 
| #include <google/protobuf/generated_message_reflection.h> | 
| +#include <google/protobuf/arenastring.h> | 
| +#include <google/protobuf/map_field_inl.h> | 
| #include <google/protobuf/reflection_ops.h> | 
| #include <google/protobuf/repeated_field.h> | 
| +#include <google/protobuf/map_type_handler.h> | 
| #include <google/protobuf/extension_set.h> | 
| #include <google/protobuf/wire_format.h> | 
| +#include <google/protobuf/map_field.h> | 
|  | 
| namespace google { | 
| namespace protobuf { | 
| @@ -83,13 +92,21 @@ namespace protobuf { | 
| using internal::WireFormat; | 
| using internal::ExtensionSet; | 
| using internal::GeneratedMessageReflection; | 
| +using internal::MapField; | 
| +using internal::DynamicMapField; | 
|  | 
|  | 
| +using internal::ArenaStringPtr; | 
| + | 
| // =================================================================== | 
| // Some helper tables and functions... | 
|  | 
| namespace { | 
|  | 
| +bool IsMapFieldInApi(const FieldDescriptor* field) { | 
| +  return field->is_map(); | 
| +} | 
| + | 
| // Compute the byte size of the in-memory representation of the field. | 
| int FieldSpaceUsed(const FieldDescriptor* field) { | 
| typedef FieldDescriptor FD;  // avoid line wrapping | 
| @@ -103,7 +120,12 @@ int FieldSpaceUsed(const FieldDescriptor* field) { | 
| case FD::CPPTYPE_FLOAT  : return sizeof(RepeatedField<float   >); | 
| case FD::CPPTYPE_BOOL   : return sizeof(RepeatedField<bool    >); | 
| case FD::CPPTYPE_ENUM   : return sizeof(RepeatedField<int     >); | 
| -      case FD::CPPTYPE_MESSAGE: return sizeof(RepeatedPtrField<Message>); | 
| +      case FD::CPPTYPE_MESSAGE: | 
| +        if (IsMapFieldInApi(field)) { | 
| +          return sizeof(DynamicMapField); | 
| +        } else { | 
| +          return sizeof(RepeatedPtrField<Message>); | 
| +        } | 
|  | 
| case FD::CPPTYPE_STRING: | 
| switch (field->options().ctype()) { | 
| @@ -131,7 +153,7 @@ int FieldSpaceUsed(const FieldDescriptor* field) { | 
| switch (field->options().ctype()) { | 
| default:  // TODO(kenton):  Support other string reps. | 
| case FieldOptions::STRING: | 
| -            return sizeof(string*); | 
| +            return sizeof(ArenaStringPtr); | 
| } | 
| break; | 
| } | 
| @@ -141,11 +163,42 @@ int FieldSpaceUsed(const FieldDescriptor* field) { | 
| return 0; | 
| } | 
|  | 
| +// Compute the byte size of in-memory representation of the oneof fields | 
| +// in default oneof instance. | 
| +int OneofFieldSpaceUsed(const FieldDescriptor* field) { | 
| +  typedef FieldDescriptor FD;  // avoid line wrapping | 
| +  switch (field->cpp_type()) { | 
| +    case FD::CPPTYPE_INT32  : return sizeof(int32   ); | 
| +    case FD::CPPTYPE_INT64  : return sizeof(int64   ); | 
| +    case FD::CPPTYPE_UINT32 : return sizeof(uint32  ); | 
| +    case FD::CPPTYPE_UINT64 : return sizeof(uint64  ); | 
| +    case FD::CPPTYPE_DOUBLE : return sizeof(double  ); | 
| +    case FD::CPPTYPE_FLOAT  : return sizeof(float   ); | 
| +    case FD::CPPTYPE_BOOL   : return sizeof(bool    ); | 
| +    case FD::CPPTYPE_ENUM   : return sizeof(int     ); | 
| + | 
| +    case FD::CPPTYPE_MESSAGE: | 
| +      return sizeof(Message*); | 
| + | 
| +    case FD::CPPTYPE_STRING: | 
| +      switch (field->options().ctype()) { | 
| +        default: | 
| +        case FieldOptions::STRING: | 
| +          return sizeof(ArenaStringPtr); | 
| +      } | 
| +      break; | 
| +  } | 
| + | 
| +  GOOGLE_LOG(DFATAL) << "Can't get here."; | 
| +  return 0; | 
| +} | 
| + | 
| inline int DivideRoundingUp(int i, int j) { | 
| return (i + (j - 1)) / j; | 
| } | 
|  | 
| static const int kSafeAlignment = sizeof(uint64); | 
| +static const int kMaxOneofUnionSize = sizeof(uint64); | 
|  | 
| inline int AlignTo(int offset, int alignment) { | 
| return DivideRoundingUp(offset, alignment) * alignment; | 
| @@ -168,8 +221,10 @@ class DynamicMessage : public Message { | 
| struct TypeInfo { | 
| int size; | 
| int has_bits_offset; | 
| +    int oneof_case_offset; | 
| int unknown_fields_offset; | 
| int extensions_offset; | 
| +    int is_default_instance_offset; | 
|  | 
| // Not owned by the TypeInfo. | 
| DynamicMessageFactory* factory;  // The factory that created this object. | 
| @@ -178,18 +233,20 @@ class DynamicMessage : public Message { | 
|  | 
| // Warning:  The order in which the following pointers are defined is | 
| //   important (the prototype must be deleted *before* the offsets). | 
| -    scoped_array<int> offsets; | 
| -    scoped_ptr<const GeneratedMessageReflection> reflection; | 
| +    google::protobuf::scoped_array<int> offsets; | 
| +    google::protobuf::scoped_ptr<const GeneratedMessageReflection> reflection; | 
| // Don't use a scoped_ptr to hold the prototype: the destructor for | 
| // DynamicMessage needs to know whether it is the prototype, and does so by | 
| // looking back at this field. This would assume details about the | 
| // implementation of scoped_ptr. | 
| const DynamicMessage* prototype; | 
| +    void* default_oneof_instance; | 
|  | 
| -    TypeInfo() : prototype(NULL) {} | 
| +    TypeInfo() : prototype(NULL), default_oneof_instance(NULL) {} | 
|  | 
| ~TypeInfo() { | 
| delete prototype; | 
| +      operator delete(default_oneof_instance); | 
| } | 
| }; | 
|  | 
| @@ -202,14 +259,19 @@ class DynamicMessage : public Message { | 
| // implements Message ---------------------------------------------- | 
|  | 
| Message* New() const; | 
| +  Message* New(::google::protobuf::Arena* arena) const; | 
| +  ::google::protobuf::Arena* GetArena() const { return NULL; }; | 
|  | 
| int GetCachedSize() const; | 
| void SetCachedSize(int size) const; | 
|  | 
| Metadata GetMetadata() const; | 
|  | 
| + | 
| private: | 
| GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage); | 
| +  DynamicMessage(const TypeInfo* type_info, ::google::protobuf::Arena* arena); | 
| +  void SharedCtor(); | 
|  | 
| inline bool is_prototype() const { | 
| return type_info_->prototype == this || | 
| @@ -226,7 +288,6 @@ class DynamicMessage : public Message { | 
| } | 
|  | 
| const TypeInfo* type_info_; | 
| - | 
| // TODO(kenton):  Make this an atomic<int> when C++ supports it. | 
| mutable int cached_byte_size_; | 
| }; | 
| @@ -234,6 +295,17 @@ class DynamicMessage : public Message { | 
| DynamicMessage::DynamicMessage(const TypeInfo* type_info) | 
| : type_info_(type_info), | 
| cached_byte_size_(0) { | 
| +  SharedCtor(); | 
| +} | 
| + | 
| +DynamicMessage::DynamicMessage(const TypeInfo* type_info, | 
| +                               ::google::protobuf::Arena* arena) | 
| +  : type_info_(type_info), | 
| +    cached_byte_size_(0) { | 
| +  SharedCtor(); | 
| +} | 
| + | 
| +void DynamicMessage::SharedCtor() { | 
| // We need to call constructors for various fields manually and set | 
| // default values where appropriate.  We use placement new to call | 
| // constructors.  If you haven't heard of placement new, I suggest Googling | 
| @@ -245,6 +317,17 @@ DynamicMessage::DynamicMessage(const TypeInfo* type_info) | 
|  | 
| const Descriptor* descriptor = type_info_->type; | 
|  | 
| +  // Initialize oneof cases. | 
| +  for (int i = 0 ; i < descriptor->oneof_decl_count(); ++i) { | 
| +    new(OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i)) | 
| +        uint32(0); | 
| +  } | 
| + | 
| +  if (type_info_->is_default_instance_offset != -1) { | 
| +    *reinterpret_cast<bool*>( | 
| +        OffsetToPointer(type_info_->is_default_instance_offset)) = false; | 
| +  } | 
| + | 
| new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet; | 
|  | 
| if (type_info_->extensions_offset != -1) { | 
| @@ -254,6 +337,9 @@ DynamicMessage::DynamicMessage(const TypeInfo* type_info) | 
| for (int i = 0; i < descriptor->field_count(); i++) { | 
| const FieldDescriptor* field = descriptor->field(i); | 
| void* field_ptr = OffsetToPointer(type_info_->offsets[i]); | 
| +    if (field->containing_oneof()) { | 
| +      continue; | 
| +    } | 
| switch (field->cpp_type()) { | 
| #define HANDLE_TYPE(CPPTYPE, TYPE)                                           \ | 
| case FieldDescriptor::CPPTYPE_##CPPTYPE:                               \ | 
| @@ -286,15 +372,17 @@ DynamicMessage::DynamicMessage(const TypeInfo* type_info) | 
| default:  // TODO(kenton):  Support other string reps. | 
| case FieldOptions::STRING: | 
| if (!field->is_repeated()) { | 
| +              const string* default_value; | 
| if (is_prototype()) { | 
| -                new(field_ptr) const string*(&field->default_value_string()); | 
| +                default_value = &field->default_value_string(); | 
| } else { | 
| -                string* default_value = | 
| -                  *reinterpret_cast<string* const*>( | 
| +                default_value = | 
| +                  &(reinterpret_cast<const ArenaStringPtr*>( | 
| type_info_->prototype->OffsetToPointer( | 
| -                      type_info_->offsets[i])); | 
| -                new(field_ptr) string*(default_value); | 
| +                      type_info_->offsets[i]))->Get(NULL)); | 
| } | 
| +              ArenaStringPtr* asp = new(field_ptr) ArenaStringPtr(); | 
| +              asp->UnsafeSetDefault(default_value); | 
| } else { | 
| new(field_ptr) RepeatedPtrField<string>(); | 
| } | 
| @@ -306,7 +394,12 @@ DynamicMessage::DynamicMessage(const TypeInfo* type_info) | 
| if (!field->is_repeated()) { | 
| new(field_ptr) Message*(NULL); | 
| } else { | 
| -          new(field_ptr) RepeatedPtrField<Message>(); | 
| +          if (IsMapFieldInApi(field)) { | 
| +            new (field_ptr) DynamicMapField( | 
| +                type_info_->factory->GetPrototypeNoLock(field->message_type())); | 
| +          } else { | 
| +            new (field_ptr) RepeatedPtrField<Message>(); | 
| +          } | 
| } | 
| break; | 
| } | 
| @@ -327,12 +420,41 @@ DynamicMessage::~DynamicMessage() { | 
|  | 
| // We need to manually run the destructors for repeated fields and strings, | 
| // just as we ran their constructors in the the DynamicMessage constructor. | 
| +  // We also need to manually delete oneof fields if it is set and is string | 
| +  // or message. | 
| // Additionally, if any singular embedded messages have been allocated, we | 
| // need to delete them, UNLESS we are the prototype message of this type, | 
| // in which case any embedded messages are other prototypes and shouldn't | 
| // be touched. | 
| for (int i = 0; i < descriptor->field_count(); i++) { | 
| const FieldDescriptor* field = descriptor->field(i); | 
| +    if (field->containing_oneof()) { | 
| +      void* field_ptr = OffsetToPointer( | 
| +          type_info_->oneof_case_offset | 
| +          + sizeof(uint32) * field->containing_oneof()->index()); | 
| +      if (*(reinterpret_cast<const uint32*>(field_ptr)) == | 
| +          field->number()) { | 
| +        field_ptr = OffsetToPointer(type_info_->offsets[ | 
| +            descriptor->field_count() + field->containing_oneof()->index()]); | 
| +        if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { | 
| +          switch (field->options().ctype()) { | 
| +            default: | 
| +            case FieldOptions::STRING: { | 
| +              const ::std::string* default_value = | 
| +                  &(reinterpret_cast<const ArenaStringPtr*>( | 
| +                      type_info_->prototype->OffsetToPointer( | 
| +                          type_info_->offsets[i]))->Get(NULL)); | 
| +              reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( | 
| +                  default_value, NULL); | 
| +              break; | 
| +            } | 
| +          } | 
| +        } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { | 
| +            delete *reinterpret_cast<Message**>(field_ptr); | 
| +        } | 
| +      } | 
| +      continue; | 
| +    } | 
| void* field_ptr = OffsetToPointer(type_info_->offsets[i]); | 
|  | 
| if (field->is_repeated()) { | 
| @@ -364,8 +486,12 @@ DynamicMessage::~DynamicMessage() { | 
| break; | 
|  | 
| case FieldDescriptor::CPPTYPE_MESSAGE: | 
| -          reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr) | 
| -              ->~RepeatedPtrField<Message>(); | 
| +          if (IsMapFieldInApi(field)) { | 
| +            reinterpret_cast<DynamicMapField*>(field_ptr)->~DynamicMapField(); | 
| +          } else { | 
| +            reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr) | 
| +                ->~RepeatedPtrField<Message>(); | 
| +          } | 
| break; | 
| } | 
|  | 
| @@ -373,10 +499,12 @@ DynamicMessage::~DynamicMessage() { | 
| switch (field->options().ctype()) { | 
| default:  // TODO(kenton):  Support other string reps. | 
| case FieldOptions::STRING: { | 
| -          string* ptr = *reinterpret_cast<string**>(field_ptr); | 
| -          if (ptr != &field->default_value_string()) { | 
| -            delete ptr; | 
| -          } | 
| +          const ::std::string* default_value = | 
| +              &(reinterpret_cast<const ArenaStringPtr*>( | 
| +                  type_info_->prototype->OffsetToPointer( | 
| +                      type_info_->offsets[i]))->Get(NULL)); | 
| +          reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy( | 
| +              default_value, NULL); | 
| break; | 
| } | 
| } | 
| @@ -402,6 +530,10 @@ void DynamicMessage::CrossLinkPrototypes() { | 
| for (int i = 0; i < descriptor->field_count(); i++) { | 
| const FieldDescriptor* field = descriptor->field(i); | 
| void* field_ptr = OffsetToPointer(type_info_->offsets[i]); | 
| +    if (field->containing_oneof()) { | 
| +      field_ptr = reinterpret_cast<uint8*>( | 
| +          type_info_->default_oneof_instance) + type_info_->offsets[i]; | 
| +    } | 
|  | 
| if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && | 
| !field->is_repeated()) { | 
| @@ -413,6 +545,14 @@ void DynamicMessage::CrossLinkPrototypes() { | 
| factory->GetPrototypeNoLock(field->message_type()); | 
| } | 
| } | 
| + | 
| +  // Set as the default instance -- this affects field-presence semantics for | 
| +  // proto3. | 
| +  if (type_info_->is_default_instance_offset != -1) { | 
| +    void* is_default_instance_ptr = | 
| +        OffsetToPointer(type_info_->is_default_instance_offset); | 
| +    *reinterpret_cast<bool*>(is_default_instance_ptr) = true; | 
| +  } | 
| } | 
|  | 
| Message* DynamicMessage::New() const { | 
| @@ -421,6 +561,16 @@ Message* DynamicMessage::New() const { | 
| return new(new_base) DynamicMessage(type_info_); | 
| } | 
|  | 
| +Message* DynamicMessage::New(::google::protobuf::Arena* arena) const { | 
| +  if (arena != NULL) { | 
| +    Message* message = New(); | 
| +    arena->Own(message); | 
| +    return message; | 
| +  } else { | 
| +    return New(); | 
| +  } | 
| +} | 
| + | 
| int DynamicMessage::GetCachedSize() const { | 
| return cached_byte_size_; | 
| } | 
| @@ -429,7 +579,9 @@ void DynamicMessage::SetCachedSize(int size) const { | 
| // This is theoretically not thread-compatible, but in practice it works | 
| // because if multiple threads write this simultaneously, they will be | 
| // writing the exact same value. | 
| +  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); | 
| cached_byte_size_ = size; | 
| +  GOOGLE_SAFE_CONCURRENT_WRITES_END(); | 
| } | 
|  | 
| Metadata DynamicMessage::GetMetadata() const { | 
| @@ -459,6 +611,9 @@ DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool) | 
| DynamicMessageFactory::~DynamicMessageFactory() { | 
| for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin(); | 
| iter != prototypes_->map_.end(); ++iter) { | 
| +    DeleteDefaultOneofInstance(iter->second->type, | 
| +                               iter->second->offsets.get(), | 
| +                               iter->second->default_oneof_instance); | 
| delete iter->second; | 
| } | 
| } | 
| @@ -497,7 +652,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( | 
| //   or not that field is set. | 
|  | 
| // Compute size and offsets. | 
| -  int* offsets = new int[type->field_count()]; | 
| +  int* offsets = new int[type->field_count() + type->oneof_decl_count()]; | 
| type_info->offsets.reset(offsets); | 
|  | 
| // Decide all field offsets by packing in order. | 
| @@ -507,11 +662,31 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( | 
| size = AlignOffset(size); | 
|  | 
| // Next the has_bits, which is an array of uint32s. | 
| -  type_info->has_bits_offset = size; | 
| -  int has_bits_array_size = | 
| -    DivideRoundingUp(type->field_count(), bitsizeof(uint32)); | 
| -  size += has_bits_array_size * sizeof(uint32); | 
| -  size = AlignOffset(size); | 
| +  if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { | 
| +    type_info->has_bits_offset = -1; | 
| +  } else { | 
| +    type_info->has_bits_offset = size; | 
| +    int has_bits_array_size = | 
| +      DivideRoundingUp(type->field_count(), bitsizeof(uint32)); | 
| +    size += has_bits_array_size * sizeof(uint32); | 
| +    size = AlignOffset(size); | 
| +  } | 
| + | 
| +  // The is_default_instance member, if any. | 
| +  if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { | 
| +    type_info->is_default_instance_offset = size; | 
| +    size += sizeof(bool); | 
| +    size = AlignOffset(size); | 
| +  } else { | 
| +    type_info->is_default_instance_offset = -1; | 
| +  } | 
| + | 
| +  // The oneof_case, if any. It is an array of uint32s. | 
| +  if (type->oneof_decl_count() > 0) { | 
| +    type_info->oneof_case_offset = size; | 
| +    size += type->oneof_decl_count() * sizeof(uint32); | 
| +    size = AlignOffset(size); | 
| +  } | 
|  | 
| // The ExtensionSet, if any. | 
| if (type->extension_range_count() > 0) { | 
| @@ -526,10 +701,20 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( | 
| // All the fields. | 
| for (int i = 0; i < type->field_count(); i++) { | 
| // Make sure field is aligned to avoid bus errors. | 
| -    int field_size = FieldSpaceUsed(type->field(i)); | 
| -    size = AlignTo(size, min(kSafeAlignment, field_size)); | 
| -    offsets[i] = size; | 
| -    size += field_size; | 
| +    // Oneof fields do not use any space. | 
| +    if (!type->field(i)->containing_oneof()) { | 
| +      int field_size = FieldSpaceUsed(type->field(i)); | 
| +      size = AlignTo(size, min(kSafeAlignment, field_size)); | 
| +      offsets[i] = size; | 
| +      size += field_size; | 
| +    } | 
| +  } | 
| + | 
| +  // The oneofs. | 
| +  for (int i = 0; i < type->oneof_decl_count(); i++) { | 
| +    size = AlignTo(size, kSafeAlignment); | 
| +    offsets[type->field_count() + i] = size; | 
| +    size += kMaxOneofUnionSize; | 
| } | 
|  | 
| // Add the UnknownFieldSet to the end. | 
| @@ -545,27 +730,133 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( | 
| // Allocate the prototype. | 
| void* base = operator new(size); | 
| memset(base, 0, size); | 
| +  // The prototype in type_info has to be set before creating the prototype | 
| +  // instance on memory. e.g., message Foo { map<int32, Foo> a = 1; }. When | 
| +  // creating prototype for Foo, prototype of the map entry will also be | 
| +  // created, which needs the address of the prototype of Foo (the value in | 
| +  // map). To break the cyclic dependency, we have to assgin the address of | 
| +  // prototype into type_info first. | 
| +  type_info->prototype = static_cast<DynamicMessage*>(base); | 
| DynamicMessage* prototype = new(base) DynamicMessage(type_info); | 
| -  type_info->prototype = prototype; | 
|  | 
| // Construct the reflection object. | 
| -  type_info->reflection.reset( | 
| -    new GeneratedMessageReflection( | 
| -      type_info->type, | 
| -      type_info->prototype, | 
| -      type_info->offsets.get(), | 
| -      type_info->has_bits_offset, | 
| -      type_info->unknown_fields_offset, | 
| -      type_info->extensions_offset, | 
| -      type_info->pool, | 
| -      this, | 
| -      type_info->size)); | 
| - | 
| +  if (type->oneof_decl_count() > 0) { | 
| +    // Compute the size of default oneof instance and offsets of default | 
| +    // oneof fields. | 
| +    int oneof_size = 0; | 
| +    for (int i = 0; i < type->oneof_decl_count(); i++) { | 
| +      for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { | 
| +        const FieldDescriptor* field = type->oneof_decl(i)->field(j); | 
| +        int field_size = OneofFieldSpaceUsed(field); | 
| +        oneof_size = AlignTo(oneof_size, min(kSafeAlignment, field_size)); | 
| +        offsets[field->index()] = oneof_size; | 
| +        oneof_size += field_size; | 
| +      } | 
| +    } | 
| +    // Construct default oneof instance. | 
| +    type_info->default_oneof_instance = ::operator new(oneof_size); | 
| +    ConstructDefaultOneofInstance(type_info->type, | 
| +                                  type_info->offsets.get(), | 
| +                                  type_info->default_oneof_instance); | 
| +    type_info->reflection.reset( | 
| +        new GeneratedMessageReflection( | 
| +            type_info->type, | 
| +            type_info->prototype, | 
| +            type_info->offsets.get(), | 
| +            type_info->has_bits_offset, | 
| +            type_info->unknown_fields_offset, | 
| +            type_info->extensions_offset, | 
| +            type_info->default_oneof_instance, | 
| +            type_info->oneof_case_offset, | 
| +            type_info->pool, | 
| +            this, | 
| +            type_info->size, | 
| +            -1 /* arena_offset */, | 
| +            type_info->is_default_instance_offset)); | 
| +  } else { | 
| +    type_info->reflection.reset( | 
| +        new GeneratedMessageReflection( | 
| +            type_info->type, | 
| +            type_info->prototype, | 
| +            type_info->offsets.get(), | 
| +            type_info->has_bits_offset, | 
| +            type_info->unknown_fields_offset, | 
| +            type_info->extensions_offset, | 
| +            type_info->pool, | 
| +            this, | 
| +            type_info->size, | 
| +            -1 /* arena_offset */, | 
| +            type_info->is_default_instance_offset)); | 
| +  } | 
| // Cross link prototypes. | 
| prototype->CrossLinkPrototypes(); | 
|  | 
| return prototype; | 
| } | 
|  | 
| +void DynamicMessageFactory::ConstructDefaultOneofInstance( | 
| +    const Descriptor* type, | 
| +    const int offsets[], | 
| +    void* default_oneof_instance) { | 
| +  for (int i = 0; i < type->oneof_decl_count(); i++) { | 
| +    for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { | 
| +      const FieldDescriptor* field = type->oneof_decl(i)->field(j); | 
| +      void* field_ptr = reinterpret_cast<uint8*>( | 
| +          default_oneof_instance) + offsets[field->index()]; | 
| +      switch (field->cpp_type()) { | 
| +#define HANDLE_TYPE(CPPTYPE, TYPE)                                      \ | 
| +        case FieldDescriptor::CPPTYPE_##CPPTYPE:                        \ | 
| +          new(field_ptr) TYPE(field->default_value_##TYPE());           \ | 
| +          break; | 
| + | 
| +        HANDLE_TYPE(INT32 , int32 ); | 
| +        HANDLE_TYPE(INT64 , int64 ); | 
| +        HANDLE_TYPE(UINT32, uint32); | 
| +        HANDLE_TYPE(UINT64, uint64); | 
| +        HANDLE_TYPE(DOUBLE, double); | 
| +        HANDLE_TYPE(FLOAT , float ); | 
| +        HANDLE_TYPE(BOOL  , bool  ); | 
| +#undef HANDLE_TYPE | 
| + | 
| +        case FieldDescriptor::CPPTYPE_ENUM: | 
| +          new(field_ptr) int(field->default_value_enum()->number()); | 
| +          break; | 
| +        case FieldDescriptor::CPPTYPE_STRING: | 
| +          switch (field->options().ctype()) { | 
| +            default: | 
| +            case FieldOptions::STRING: | 
| +              ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr(); | 
| +              asp->UnsafeSetDefault(&field->default_value_string()); | 
| +              break; | 
| +          } | 
| +          break; | 
| + | 
| +        case FieldDescriptor::CPPTYPE_MESSAGE: { | 
| +          new(field_ptr) Message*(NULL); | 
| +          break; | 
| +        } | 
| +      } | 
| +    } | 
| +  } | 
| +} | 
| + | 
| +void DynamicMessageFactory::DeleteDefaultOneofInstance( | 
| +    const Descriptor* type, | 
| +    const int offsets[], | 
| +    void* default_oneof_instance) { | 
| +  for (int i = 0; i < type->oneof_decl_count(); i++) { | 
| +    for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { | 
| +      const FieldDescriptor* field = type->oneof_decl(i)->field(j); | 
| +      if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { | 
| +        switch (field->options().ctype()) { | 
| +          default: | 
| +          case FieldOptions::STRING: | 
| +            break; | 
| +        } | 
| +      } | 
| +    } | 
| +  } | 
| +} | 
| + | 
| }  // namespace protobuf | 
| }  // namespace google | 
|  |