Index: third_party/protobuf/src/google/protobuf/extension_set_heavy.cc |
diff --git a/third_party/protobuf/src/google/protobuf/extension_set_heavy.cc b/third_party/protobuf/src/google/protobuf/extension_set_heavy.cc |
index 01b9490bfa36986866548d5c963ec26fb683c597..82e3e099631aba56150995ddd9f28a686a826f1f 100644 |
--- a/third_party/protobuf/src/google/protobuf/extension_set_heavy.cc |
+++ b/third_party/protobuf/src/google/protobuf/extension_set_heavy.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 |
@@ -48,6 +48,29 @@ namespace google { |
namespace protobuf { |
namespace internal { |
+// A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet. |
+class MessageSetFieldSkipper |
+ : public UnknownFieldSetFieldSkipper { |
+ public: |
+ explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields) |
+ : UnknownFieldSetFieldSkipper(unknown_fields) {} |
+ virtual ~MessageSetFieldSkipper() {} |
+ |
+ virtual bool SkipMessageSetField(io::CodedInputStream* input, |
+ int field_number); |
+}; |
+bool MessageSetFieldSkipper::SkipMessageSetField( |
+ io::CodedInputStream* input, int field_number) { |
+ uint32 length; |
+ if (!input->ReadVarint32(&length)) return false; |
+ if (unknown_fields_ == NULL) { |
+ return input->Skip(length); |
+ } else { |
+ return input->ReadString( |
+ unknown_fields_->AddLengthDelimited(field_number), length); |
+ } |
+} |
+ |
// Implementation of ExtensionFinder which finds extensions in a given |
// DescriptorPool, using the given MessageFactory to construct sub-objects. |
@@ -68,9 +91,10 @@ class DescriptorPoolExtensionFinder : public ExtensionFinder { |
const Descriptor* containing_type_; |
}; |
-void ExtensionSet::AppendToList(const Descriptor* containing_type, |
- const DescriptorPool* pool, |
- vector<const FieldDescriptor*>* output) const { |
+void ExtensionSet::AppendToList( |
+ const Descriptor* containing_type, |
+ const DescriptorPool* pool, |
+ std::vector<const FieldDescriptor*>* output) const { |
for (map<int, Extension>::const_iterator iter = extensions_.begin(); |
iter != extensions_.end(); ++iter) { |
bool has = false; |
@@ -146,7 +170,7 @@ MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor, |
const MessageLite* prototype = |
factory->GetPrototype(descriptor->message_type()); |
extension->is_lazy = false; |
- extension->message_value = prototype->New(); |
+ extension->message_value = prototype->New(arena_); |
extension->is_cleared = false; |
return extension->message_value; |
} else { |
@@ -172,28 +196,40 @@ MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor, |
MessageLite* ret = NULL; |
if (iter->second.is_lazy) { |
ret = iter->second.lazymessage_value->ReleaseMessage( |
- *factory->GetPrototype(descriptor->message_type())); |
- delete iter->second.lazymessage_value; |
+ *factory->GetPrototype(descriptor->message_type())); |
+ if (arena_ == NULL) { |
+ delete iter->second.lazymessage_value; |
+ } |
} else { |
- ret = iter->second.message_value; |
+ if (arena_ != NULL) { |
+ ret = (iter->second.message_value)->New(); |
+ ret->CheckTypeAndMergeFrom(*(iter->second.message_value)); |
+ } else { |
+ ret = iter->second.message_value; |
+ } |
} |
extensions_.erase(descriptor->number()); |
return ret; |
} |
} |
-MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor, |
- MessageFactory* factory) { |
+ExtensionSet::Extension* ExtensionSet::MaybeNewRepeatedExtension(const FieldDescriptor* descriptor) { |
Extension* extension; |
if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) { |
extension->type = descriptor->type(); |
GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); |
extension->is_repeated = true; |
extension->repeated_message_value = |
- new RepeatedPtrField<MessageLite>(); |
+ ::google::protobuf::Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_); |
} else { |
GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); |
} |
+ return extension; |
+} |
+ |
+MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor, |
+ MessageFactory* factory) { |
+ Extension* extension = MaybeNewRepeatedExtension(descriptor); |
// RepeatedPtrField<Message> does not know how to Add() since it cannot |
// allocate an abstract object, so we have to be tricky. |
@@ -207,12 +243,19 @@ MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor, |
} else { |
prototype = &extension->repeated_message_value->Get(0); |
} |
- result = prototype->New(); |
+ result = prototype->New(arena_); |
extension->repeated_message_value->AddAllocated(result); |
} |
return result; |
} |
+void ExtensionSet::AddAllocatedMessage(const FieldDescriptor* descriptor, |
+ MessageLite* new_entry) { |
+ Extension* extension = MaybeNewRepeatedExtension(descriptor); |
+ |
+ extension->repeated_message_value->AddAllocated(new_entry); |
+} |
+ |
static bool ValidateEnumUsingDescriptor(const void* arg, int number) { |
return reinterpret_cast<const EnumDescriptor*>(arg) |
->FindValueByNumber(number) != NULL; |
@@ -243,10 +286,10 @@ bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) { |
} |
} |
-bool ExtensionSet::ParseFieldHeavy(uint32 tag, io::CodedInputStream* input, |
- const Message* containing_type, |
- UnknownFieldSet* unknown_fields) { |
- FieldSkipper skipper(unknown_fields); |
+bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, |
+ const Message* containing_type, |
+ UnknownFieldSet* unknown_fields) { |
+ UnknownFieldSetFieldSkipper skipper(unknown_fields); |
if (input->GetExtensionPool() == NULL) { |
GeneratedExtensionFinder finder(containing_type); |
return ParseField(tag, input, &finder, &skipper); |
@@ -258,10 +301,10 @@ bool ExtensionSet::ParseFieldHeavy(uint32 tag, io::CodedInputStream* input, |
} |
} |
-bool ExtensionSet::ParseMessageSetHeavy(io::CodedInputStream* input, |
- const Message* containing_type, |
- UnknownFieldSet* unknown_fields) { |
- FieldSkipper skipper(unknown_fields); |
+bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, |
+ const Message* containing_type, |
+ UnknownFieldSet* unknown_fields) { |
+ MessageSetFieldSkipper skipper(unknown_fields); |
if (input->GetExtensionPool() == NULL) { |
GeneratedExtensionFinder finder(containing_type); |
return ParseMessageSet(input, &finder, &skipper); |
@@ -511,17 +554,19 @@ uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray( |
bool ExtensionSet::ParseFieldMaybeLazily( |
- uint32 tag, io::CodedInputStream* input, |
+ int wire_type, int field_number, io::CodedInputStream* input, |
ExtensionFinder* extension_finder, |
- FieldSkipper* field_skipper) { |
- return ParseField(tag, input, extension_finder, field_skipper); |
+ MessageSetFieldSkipper* field_skipper) { |
+ return ParseField(WireFormatLite::MakeTag( |
+ field_number, static_cast<WireFormatLite::WireType>(wire_type)), |
+ input, extension_finder, field_skipper); |
} |
bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, |
ExtensionFinder* extension_finder, |
- FieldSkipper* field_skipper) { |
+ MessageSetFieldSkipper* field_skipper) { |
while (true) { |
- uint32 tag = input->ReadTag(); |
+ const uint32 tag = input->ReadTag(); |
switch (tag) { |
case 0: |
return true; |
@@ -540,16 +585,15 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, |
} |
bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, |
- const MessageLite* containing_type, |
- UnknownFieldSet* unknown_fields) { |
- FieldSkipper skipper(unknown_fields); |
+ const MessageLite* containing_type) { |
+ MessageSetFieldSkipper skipper(NULL); |
GeneratedExtensionFinder finder(containing_type); |
return ParseMessageSet(input, &finder, &skipper); |
} |
bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, |
ExtensionFinder* extension_finder, |
- FieldSkipper* field_skipper) { |
+ MessageSetFieldSkipper* field_skipper) { |
// TODO(kenton): It would be nice to share code between this and |
// WireFormatLite::ParseAndMergeMessageSetItem(), but I think the |
// differences would be hard to factor out. |
@@ -558,25 +602,21 @@ bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, |
// required int32 type_id = 2; |
// required data message = 3; |
- // Once we see a type_id, we'll construct a fake tag for this extension |
- // which is the tag it would have had under the proto2 extensions wire |
- // format. |
- uint32 fake_tag = 0; |
+ uint32 last_type_id = 0; |
// If we see message data before the type_id, we'll append it to this so |
// we can parse it later. |
string message_data; |
while (true) { |
- uint32 tag = input->ReadTag(); |
+ const uint32 tag = input->ReadTag(); |
if (tag == 0) return false; |
switch (tag) { |
case WireFormatLite::kMessageSetTypeIdTag: { |
uint32 type_id; |
if (!input->ReadVarint32(&type_id)) return false; |
- fake_tag = WireFormatLite::MakeTag(type_id, |
- WireFormatLite::WIRETYPE_LENGTH_DELIMITED); |
+ last_type_id = type_id; |
if (!message_data.empty()) { |
// We saw some message data before the type_id. Have to parse it |
@@ -584,7 +624,8 @@ bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, |
io::CodedInputStream sub_input( |
reinterpret_cast<const uint8*>(message_data.data()), |
message_data.size()); |
- if (!ParseFieldMaybeLazily(fake_tag, &sub_input, |
+ if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED, |
+ last_type_id, &sub_input, |
extension_finder, field_skipper)) { |
return false; |
} |
@@ -595,7 +636,7 @@ bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, |
} |
case WireFormatLite::kMessageSetMessageTag: { |
- if (fake_tag == 0) { |
+ if (last_type_id == 0) { |
// We haven't seen a type_id yet. Append this data to message_data. |
string temp; |
uint32 length; |
@@ -607,7 +648,8 @@ bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, |
coded_output.WriteString(temp); |
} else { |
// Already saw type_id, so we can parse this directly. |
- if (!ParseFieldMaybeLazily(fake_tag, input, |
+ if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED, |
+ last_type_id, input, |
extension_finder, field_skipper)) { |
return false; |
} |
@@ -690,8 +732,8 @@ int ExtensionSet::Extension::MessageSetItemByteSize(int number) const { |
void ExtensionSet::SerializeMessageSetWithCachedSizes( |
io::CodedOutputStream* output) const { |
- map<int, Extension>::const_iterator iter; |
- for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) { |
+ for (map<int, Extension>::const_iterator iter = extensions_.begin(); |
+ iter != extensions_.end(); ++iter) { |
iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output); |
} |
} |