aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/dynamic_message.cc
diff options
context:
space:
mode:
authorGravatar Feng Xiao <xfxyjwf@gmail.com>2014-11-26 16:15:29 -0800
committerGravatar Feng Xiao <xfxyjwf@gmail.com>2014-11-26 16:15:29 -0800
commitc25d9feb4d791513c101061578e9e54fe180aa5f (patch)
treef264d2d9edbea0cf30c875ec41e322790f852110 /src/google/protobuf/dynamic_message.cc
parent90f2f50233fc42a9e6f551ac8454c46a5df00454 (diff)
Down-integrate from internal code base.
Diffstat (limited to 'src/google/protobuf/dynamic_message.cc')
-rw-r--r--src/google/protobuf/dynamic_message.cc43
1 files changed, 36 insertions, 7 deletions
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
index 565afaab..318ce6f9 100644
--- a/src/google/protobuf/dynamic_message.cc
+++ b/src/google/protobuf/dynamic_message.cc
@@ -218,6 +218,7 @@ class DynamicMessage : public Message {
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.
@@ -316,6 +317,11 @@ void DynamicMessage::SharedCtor() {
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) {
@@ -532,6 +538,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 {
@@ -641,11 +655,24 @@ 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) {
@@ -731,7 +758,8 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
type_info->pool,
this,
type_info->size,
- -1 /* arena_offset */));
+ -1 /* arena_offset */,
+ type_info->is_default_instance_offset));
} else {
type_info->reflection.reset(
new GeneratedMessageReflection(
@@ -744,7 +772,8 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
type_info->pool,
this,
type_info->size,
- -1 /* arena_offset */));
+ -1 /* arena_offset */,
+ type_info->is_default_instance_offset));
}
// Cross link prototypes.
prototype->CrossLinkPrototypes();