From 80b1d62bfcea65c59e2160da71dad84b1bd19cef Mon Sep 17 00:00:00 2001 From: "kenton@google.com" Date: Wed, 29 Jul 2009 01:13:20 +0000 Subject: Submit recent changes from internal branch, including "lite mode" for C++ and Java. See CHANGES.txt for more details. --- src/google/protobuf/extension_set.cc | 730 +++++++++++++++++++++-------------- 1 file changed, 438 insertions(+), 292 deletions(-) (limited to 'src/google/protobuf/extension_set.cc') diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index 61b8daae..0f799a5b 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -36,14 +36,11 @@ #include #include #include -#include -#include -#include +#include #include #include -#include +#include #include -#include #include namespace google { @@ -52,13 +49,13 @@ namespace internal { namespace { -inline FieldDescriptor::Type real_type(FieldType type) { - GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE); - return static_cast(type); +inline WireFormatLite::FieldType real_type(FieldType type) { + GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE); + return static_cast(type); } -inline FieldDescriptor::CppType cpp_type(FieldType type) { - return FieldDescriptor::TypeToCppType(real_type(type)); +inline WireFormatLite::CppType cpp_type(FieldType type) { + return WireFormatLite::FieldTypeToCppType(real_type(type)); } // Registry stuff. @@ -72,13 +69,14 @@ struct ExtensionInfo { union { ExtensionSet::EnumValidityFunc* enum_is_valid; - const Message* message_prototype; + const MessageLite* message_prototype; }; }; -typedef hash_map, ExtensionInfo> ExtensionRegistry; +typedef hash_map, + ExtensionInfo> ExtensionRegistry; ExtensionRegistry* registry_ = NULL; -GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_); +GoogleOnceType registry_init_; void DeleteRegistry() { delete registry_; @@ -92,56 +90,58 @@ void InitRegistry() { // This function is only called at startup, so there is no need for thread- // safety. -void Register(const Message* containing_type, int number, ExtensionInfo info) { - GoogleOnceInit(®istry_init_, &InitRegistry); +void Register(const MessageLite* containing_type, + int number, ExtensionInfo info) { + ::google::protobuf::GoogleOnceInit(®istry_init_, &InitRegistry); if (!InsertIfNotPresent(registry_, make_pair(containing_type, number), info)) { GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \"" - << containing_type->GetDescriptor()->full_name() + << containing_type->GetTypeName() << "\", field number " << number << "."; } } const ExtensionInfo* FindRegisteredExtension( - const Message* containing_type, int number) { + const MessageLite* containing_type, int number) { return (registry_ == NULL) ? NULL : FindOrNull(*registry_, make_pair(containing_type, number)); } } // namespace -void ExtensionSet::RegisterExtension(const Message* containing_type, +void ExtensionSet::RegisterExtension(const MessageLite* containing_type, int number, FieldType type, bool is_repeated, bool is_packed) { - GOOGLE_CHECK_NE(type, FieldDescriptor::TYPE_ENUM); - GOOGLE_CHECK_NE(type, FieldDescriptor::TYPE_MESSAGE); - GOOGLE_CHECK_NE(type, FieldDescriptor::TYPE_GROUP); + GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM); + GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE); + GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP); ExtensionInfo info(type, is_repeated, is_packed); Register(containing_type, number, info); } -void ExtensionSet::RegisterEnumExtension(const Message* containing_type, +void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type, int number, FieldType type, bool is_repeated, bool is_packed, EnumValidityFunc* is_valid) { - GOOGLE_CHECK_EQ(type, FieldDescriptor::TYPE_ENUM); + GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM); ExtensionInfo info(type, is_repeated, is_packed); info.enum_is_valid = is_valid; Register(containing_type, number, info); } -void ExtensionSet::RegisterMessageExtension(const Message* containing_type, +void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type, int number, FieldType type, bool is_repeated, bool is_packed, - const Message* prototype) { - GOOGLE_CHECK(type == FieldDescriptor::TYPE_MESSAGE || - type == FieldDescriptor::TYPE_GROUP); + const MessageLite* prototype) { + GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE || + type == WireFormatLite::TYPE_GROUP); ExtensionInfo info(type, is_repeated, is_packed); info.message_prototype = prototype; Register(containing_type, number, info); } + // =================================================================== // Constructors and basic methods. @@ -154,24 +154,10 @@ ExtensionSet::~ExtensionSet() { } } -void ExtensionSet::AppendToList(const Descriptor* containing_type, - const DescriptorPool* pool, - vector* output) const { - for (map::const_iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - bool has = false; - if (iter->second.is_repeated) { - has = iter->second.GetSize() > 0; - } else { - has = !iter->second.is_cleared; - } - - if (has) { - output->push_back( - pool->FindExtensionByNumber(containing_type, iter->first)); - } - } -} +// Defined in extension_set_heavy.cc. +// void ExtensionSet::AppendToList(const Descriptor* containing_type, +// const DescriptorPool* pool, +// vector* output) const bool ExtensionSet::Has(int number) const { map::const_iterator iter = extensions_.find(number); @@ -195,11 +181,18 @@ void ExtensionSet::ClearExtension(int number) { // =================================================================== // Field accessors -#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ - GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \ - : FieldDescriptor::LABEL_OPTIONAL, \ - FieldDescriptor::LABEL_##LABEL); \ - GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE) +namespace { + +enum Cardinality { + REPEATED, + OPTIONAL +}; + +} // namespace + +#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \ + GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \ + GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE) // ------------------------------------------------------------------- // Primitives @@ -222,7 +215,7 @@ void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \ Extension* extension; \ if (MaybeNewExtension(number, &extension)) { \ extension->type = type; \ - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_##UPPERCASE);\ + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ extension->is_repeated = false; \ } else { \ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \ @@ -251,7 +244,7 @@ void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \ Extension* extension; \ if (MaybeNewExtension(number, &extension)) { \ extension->type = type; \ - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_##UPPERCASE);\ + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \ extension->is_repeated = true; \ extension->is_packed = packed; \ extension->repeated_##LOWERCASE##_value = new RepeatedField(); \ @@ -290,7 +283,7 @@ void ExtensionSet::SetEnum(int number, FieldType type, int value) { Extension* extension; if (MaybeNewExtension(number, &extension)) { extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_ENUM); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); extension->is_repeated = false; } else { GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM); @@ -318,7 +311,7 @@ void ExtensionSet::AddEnum(int number, FieldType type, Extension* extension; if (MaybeNewExtension(number, &extension)) { extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_ENUM); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM); extension->is_repeated = true; extension->is_packed = packed; extension->repeated_enum_value = new RepeatedField(); @@ -348,7 +341,7 @@ string* ExtensionSet::MutableString(int number, FieldType type) { Extension* extension; if (MaybeNewExtension(number, &extension)) { extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_STRING); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); extension->is_repeated = false; extension->string_value = new string; } else { @@ -376,7 +369,7 @@ string* ExtensionSet::AddString(int number, FieldType type) { Extension* extension; if (MaybeNewExtension(number, &extension)) { extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_STRING); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING); extension->is_repeated = true; extension->is_packed = false; extension->repeated_string_value = new RepeatedPtrField(); @@ -389,8 +382,8 @@ string* ExtensionSet::AddString(int number, FieldType type) { // ------------------------------------------------------------------- // Messages -const Message& ExtensionSet::GetMessage(int number, - const Message& default_value) const { +const MessageLite& ExtensionSet::GetMessage( + int number, const MessageLite& default_value) const { map::const_iterator iter = extensions_.find(number); if (iter == extensions_.end()) { // Not present. Return the default value. @@ -401,25 +394,17 @@ const Message& ExtensionSet::GetMessage(int number, } } -const Message& ExtensionSet::GetMessage(int number, - const Descriptor* message_type, - MessageFactory* factory) const { - map::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end() || iter->second.is_cleared) { - // Not present. Return the default value. - return *factory->GetPrototype(message_type); - } else { - GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE); - return *iter->second.message_value; - } -} +// Defined in extension_set_heavy.cc. +// const MessageLite& ExtensionSet::GetMessage(int number, +// const Descriptor* message_type, +// MessageFactory* factory) const -Message* ExtensionSet::MutableMessage(int number, FieldType type, - const Message& prototype) { +MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, + const MessageLite& prototype) { Extension* extension; if (MaybeNewExtension(number, &extension)) { extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); extension->is_repeated = false; extension->message_value = prototype.New(); } else { @@ -429,72 +414,55 @@ Message* ExtensionSet::MutableMessage(int number, FieldType type, return extension->message_value; } -Message* ExtensionSet::MutableMessage(int number, FieldType type, - const Descriptor* message_type, - MessageFactory* factory) { - Extension* extension; - if (MaybeNewExtension(number, &extension)) { - extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); - extension->is_repeated = false; - extension->is_packed = false; - const Message* prototype = factory->GetPrototype(message_type); - GOOGLE_CHECK(prototype != NULL); - extension->message_value = prototype->New(); - } else { - GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE); - } - extension->is_cleared = false; - return extension->message_value; -} +// Defined in extension_set_heavy.cc. +// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type, +// const Descriptor* message_type, +// MessageFactory* factory) -const Message& ExtensionSet::GetRepeatedMessage(int number, int index) const { +const MessageLite& ExtensionSet::GetRepeatedMessage( + int number, int index) const { map::const_iterator iter = extensions_.find(number); GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE); return iter->second.repeated_message_value->Get(index); } -Message* ExtensionSet::MutableRepeatedMessage(int number, int index) { +MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) { map::iterator iter = extensions_.find(number); GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE); return iter->second.repeated_message_value->Mutable(index); } -Message* ExtensionSet::AddMessage(int number, FieldType type, - const Message& prototype) { +MessageLite* ExtensionSet::AddMessage(int number, FieldType type, + const MessageLite& prototype) { Extension* extension; if (MaybeNewExtension(number, &extension)) { extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); + GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); extension->is_repeated = true; extension->repeated_message_value = - new RepeatedPtrField(&prototype); + new RepeatedPtrField(); } else { GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); } - return extension->repeated_message_value->Add(); -} -Message* ExtensionSet::AddMessage(int number, FieldType type, - const Descriptor* message_type, - MessageFactory* factory) { - Extension* extension; - if (MaybeNewExtension(number, &extension)) { - extension->type = type; - GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); - extension->is_repeated = true; - const Message* prototype = factory->GetPrototype(message_type); - GOOGLE_CHECK(prototype != NULL); - extension->repeated_message_value = - new RepeatedPtrField(prototype); - } else { - GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); + // RepeatedPtrField does not know how to Add() since it cannot + // allocate an abstract object, so we have to be tricky. + MessageLite* result = extension->repeated_message_value + ->AddFromCleared >(); + if (result == NULL) { + result = prototype.New(); + extension->repeated_message_value->AddAllocated(result); } - return extension->repeated_message_value->Add(); + return result; } +// Defined in extension_set_heavy.cc. +// MessageLite* ExtensionSet::AddMessage(int number, FieldType type, +// const Descriptor* message_type, +// MessageFactory* factory) + #undef GOOGLE_DCHECK_TYPE void ExtensionSet::RemoveLast(int number) { @@ -505,35 +473,35 @@ void ExtensionSet::RemoveLast(int number) { GOOGLE_DCHECK(extension->is_repeated); switch(cpp_type(extension->type)) { - case FieldDescriptor::CPPTYPE_INT32: - extension->repeated_int32_value->RemoveLast(); + case WireFormatLite::CPPTYPE_INT32: + extension->repeated_int32_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_INT64: - extension->repeated_int64_value->RemoveLast(); + case WireFormatLite::CPPTYPE_INT64: + extension->repeated_int64_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_UINT32: - extension->repeated_uint32_value->RemoveLast(); + case WireFormatLite::CPPTYPE_UINT32: + extension->repeated_uint32_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_UINT64: - extension->repeated_uint64_value->RemoveLast(); + case WireFormatLite::CPPTYPE_UINT64: + extension->repeated_uint64_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_FLOAT: - extension->repeated_float_value->RemoveLast(); + case WireFormatLite::CPPTYPE_FLOAT: + extension->repeated_float_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_DOUBLE: - extension->repeated_double_value->RemoveLast(); + case WireFormatLite::CPPTYPE_DOUBLE: + extension->repeated_double_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_BOOL: - extension->repeated_bool_value->RemoveLast(); + case WireFormatLite::CPPTYPE_BOOL: + extension->repeated_bool_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_ENUM: - extension->repeated_enum_value->RemoveLast(); + case WireFormatLite::CPPTYPE_ENUM: + extension->repeated_enum_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_STRING: - extension->repeated_string_value->RemoveLast(); + case WireFormatLite::CPPTYPE_STRING: + extension->repeated_string_value->RemoveLast(); break; - case FieldDescriptor::CPPTYPE_MESSAGE: - extension->repeated_message_value->RemoveLast(); + case WireFormatLite::CPPTYPE_MESSAGE: + extension->repeated_message_value->RemoveLast(); break; } } @@ -546,35 +514,35 @@ void ExtensionSet::SwapElements(int number, int index1, int index2) { GOOGLE_DCHECK(extension->is_repeated); switch(cpp_type(extension->type)) { - case FieldDescriptor::CPPTYPE_INT32: + case WireFormatLite::CPPTYPE_INT32: extension->repeated_int32_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_INT64: - extension->repeated_int64_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_INT64: + extension->repeated_int64_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_UINT32: + case WireFormatLite::CPPTYPE_UINT32: extension->repeated_uint32_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_UINT64: + case WireFormatLite::CPPTYPE_UINT64: extension->repeated_uint64_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_FLOAT: - extension->repeated_float_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_FLOAT: + extension->repeated_float_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_DOUBLE: - extension->repeated_double_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_DOUBLE: + extension->repeated_double_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_BOOL: - extension->repeated_bool_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_BOOL: + extension->repeated_bool_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_ENUM: - extension->repeated_enum_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_ENUM: + extension->repeated_enum_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_STRING: - extension->repeated_string_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_STRING: + extension->repeated_string_value->SwapElements(index1, index2); break; - case FieldDescriptor::CPPTYPE_MESSAGE: - extension->repeated_message_value->SwapElements(index1, index2); + case WireFormatLite::CPPTYPE_MESSAGE: + extension->repeated_message_value->SwapElements(index1, index2); break; } } @@ -607,7 +575,7 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) { switch (cpp_type(other_extension.type)) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ if (is_new) { \ extension->repeated_##LOWERCASE##_value = \ new REPEATED_TYPE; \ @@ -627,20 +595,32 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) { HANDLE_TYPE( STRING, string, RepeatedPtrField< string>); #undef HANDLE_TYPE - case FieldDescriptor::CPPTYPE_MESSAGE: + case WireFormatLite::CPPTYPE_MESSAGE: if (is_new) { - extension->repeated_message_value = new RepeatedPtrField( - other_extension.repeated_message_value->prototype()); + extension->repeated_message_value = + new RepeatedPtrField(); + } + // We can't call RepeatedPtrField::MergeFrom() because + // it would attempt to allocate new objects. + RepeatedPtrField* other_repeated_message = + other_extension.repeated_message_value; + for (int i = 0; i < other_repeated_message->size(); i++) { + const MessageLite& other_message = other_repeated_message->Get(i); + MessageLite* target = extension->repeated_message_value + ->AddFromCleared >(); + if (target == NULL) { + target = other_message.New(); + extension->repeated_message_value->AddAllocated(target); + } + target->CheckTypeAndMergeFrom(other_message); } - extension->repeated_message_value->MergeFrom( - *other_extension.repeated_message_value); break; } } else { if (!other_extension.is_cleared) { switch (cpp_type(other_extension.type)) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ Set##CAMELCASE(iter->first, other_extension.type, \ other_extension.LOWERCASE##_value); \ break; @@ -654,14 +634,14 @@ void ExtensionSet::MergeFrom(const ExtensionSet& other) { HANDLE_TYPE( BOOL, bool, Bool); HANDLE_TYPE( ENUM, enum, Enum); #undef HANDLE_TYPE - case FieldDescriptor::CPPTYPE_STRING: + case WireFormatLite::CPPTYPE_STRING: SetString(iter->first, other_extension.type, *other_extension.string_value); break; - case FieldDescriptor::CPPTYPE_MESSAGE: + case WireFormatLite::CPPTYPE_MESSAGE: MutableMessage(iter->first, other_extension.type, *other_extension.message_value) - ->MergeFrom(*other_extension.message_value); + ->CheckTypeAndMergeFrom(*other_extension.message_value); break; } } @@ -679,7 +659,7 @@ bool ExtensionSet::IsInitialized() const { for (map::const_iterator iter = extensions_.begin(); iter != extensions_.end(); ++iter) { const Extension& extension = iter->second; - if (cpp_type(extension.type) == FieldDescriptor::CPPTYPE_MESSAGE) { + if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) { if (extension.is_repeated) { for (int i = 0; i < extension.repeated_message_value->size(); i++) { if (!extension.repeated_message_value->Get(i).IsInitialized()) { @@ -698,10 +678,10 @@ bool ExtensionSet::IsInitialized() const { } bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, - const Message* containing_type, - UnknownFieldSet* unknown_fields) { - int number = WireFormat::GetTagFieldNumber(tag); - WireFormat::WireType wire_type = WireFormat::GetTagWireType(tag); + const MessageLite* containing_type, + FieldSkipper* field_skipper) { + int number = WireFormatLite::GetTagFieldNumber(tag); + WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); const ExtensionInfo* extension = FindRegisteredExtension(containing_type, number); @@ -710,15 +690,15 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, if (extension == NULL) { is_unknown = true; } else if (extension->is_packed) { - is_unknown = (wire_type != WireFormat::WIRETYPE_LENGTH_DELIMITED); + is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED); } else { - WireFormat::WireType expected_wire_type = - WireFormat::WireTypeForFieldType(real_type(extension->type)); + WireFormatLite::WireType expected_wire_type = + WireFormatLite::WireTypeForFieldType(real_type(extension->type)); is_unknown = (wire_type != expected_wire_type); } if (is_unknown) { - WireFormat::SkipField(input, tag, unknown_fields); + field_skipper->SkipField(input, tag); } else if (extension->is_packed) { uint32 size; if (!input->ReadVarint32(&size)) return false; @@ -726,11 +706,11 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, switch (extension->type) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ + case WireFormatLite::TYPE_##UPPERCASE: \ while (input->BytesUntilLimit() > 0) { \ CPP_LOWERCASE value; \ - if (!WireFormat::Read##CAMELCASE(input, &value)) return false; \ - Add##CPP_CAMELCASE(number, FieldDescriptor::TYPE_##UPPERCASE, \ + if (!WireFormatLite::Read##CAMELCASE(input, &value)) return false; \ + Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ true, value); \ } \ break @@ -750,20 +730,20 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, HANDLE_TYPE( BOOL, Bool, Bool, bool); #undef HANDLE_TYPE - case FieldDescriptor::TYPE_ENUM: + case WireFormatLite::TYPE_ENUM: while (input->BytesUntilLimit() > 0) { int value; - if (!WireFormat::ReadEnum(input, &value)) return false; + if (!WireFormatLite::ReadEnum(input, &value)) return false; if (extension->enum_is_valid(value)) { - AddEnum(number, FieldDescriptor::TYPE_ENUM, true, value); + AddEnum(number, WireFormatLite::TYPE_ENUM, true, value); } } break; - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_BYTES: - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; break; } @@ -772,14 +752,14 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, } else { switch (extension->type) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, CPP_CAMELCASE, CPP_LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: { \ + case WireFormatLite::TYPE_##UPPERCASE: { \ CPP_LOWERCASE value; \ - if (!WireFormat::Read##CAMELCASE(input, &value)) return false; \ + if (!WireFormatLite::Read##CAMELCASE(input, &value)) return false; \ if (extension->is_repeated) { \ - Add##CPP_CAMELCASE(number, FieldDescriptor::TYPE_##UPPERCASE, \ + Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \ false, value); \ } else { \ - Set##CPP_CAMELCASE(number, FieldDescriptor::TYPE_##UPPERCASE, value);\ + Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value); \ } \ } break @@ -798,56 +778,54 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, HANDLE_TYPE( BOOL, Bool, Bool, bool); #undef HANDLE_TYPE - case FieldDescriptor::TYPE_ENUM: { + case WireFormatLite::TYPE_ENUM: { int value; - if (!WireFormat::ReadEnum(input, &value)) return false; + if (!WireFormatLite::ReadEnum(input, &value)) return false; if (!extension->enum_is_valid(value)) { // Invalid value. Treat as unknown. - if (unknown_fields != NULL) { - unknown_fields->AddVarint(number, value); - } + field_skipper->SkipUnknownEnum(number, value); } else if (extension->is_repeated) { - AddEnum(number, FieldDescriptor::TYPE_ENUM, false, value); + AddEnum(number, WireFormatLite::TYPE_ENUM, false, value); } else { - SetEnum(number, FieldDescriptor::TYPE_ENUM, value); + SetEnum(number, WireFormatLite::TYPE_ENUM, value); } break; } - case FieldDescriptor::TYPE_STRING: { + case WireFormatLite::TYPE_STRING: { string* value = extension->is_repeated ? - AddString(number, FieldDescriptor::TYPE_STRING) : - MutableString(number, FieldDescriptor::TYPE_STRING); - if (!WireFormat::ReadString(input, value)) return false; + AddString(number, WireFormatLite::TYPE_STRING) : + MutableString(number, WireFormatLite::TYPE_STRING); + if (!WireFormatLite::ReadString(input, value)) return false; break; } - case FieldDescriptor::TYPE_BYTES: { + case WireFormatLite::TYPE_BYTES: { string* value = extension->is_repeated ? - AddString(number, FieldDescriptor::TYPE_STRING) : - MutableString(number, FieldDescriptor::TYPE_STRING); - if (!WireFormat::ReadBytes(input, value)) return false; + AddString(number, WireFormatLite::TYPE_STRING) : + MutableString(number, WireFormatLite::TYPE_STRING); + if (!WireFormatLite::ReadBytes(input, value)) return false; break; } - case FieldDescriptor::TYPE_GROUP: { - Message* value = extension->is_repeated ? - AddMessage(number, FieldDescriptor::TYPE_GROUP, + case WireFormatLite::TYPE_GROUP: { + MessageLite* value = extension->is_repeated ? + AddMessage(number, WireFormatLite::TYPE_GROUP, *extension->message_prototype) : - MutableMessage(number, FieldDescriptor::TYPE_GROUP, + MutableMessage(number, WireFormatLite::TYPE_GROUP, *extension->message_prototype); - if (!WireFormat::ReadGroup(number, input, value)) return false; + if (!WireFormatLite::ReadGroup(number, input, value)) return false; break; } - case FieldDescriptor::TYPE_MESSAGE: { - Message* value = extension->is_repeated ? - AddMessage(number, FieldDescriptor::TYPE_MESSAGE, + case WireFormatLite::TYPE_MESSAGE: { + MessageLite* value = extension->is_repeated ? + AddMessage(number, WireFormatLite::TYPE_MESSAGE, *extension->message_prototype) : - MutableMessage(number, FieldDescriptor::TYPE_MESSAGE, + MutableMessage(number, WireFormatLite::TYPE_MESSAGE, *extension->message_prototype); - if (!WireFormat::ReadMessage(input, value)) return false; + if (!WireFormatLite::ReadMessage(input, value)) return false; break; } } @@ -856,6 +834,130 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, return true; } +bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, + const MessageLite* containing_type) { + FieldSkipper skipper; + return ParseField(tag, input, containing_type, &skipper); +} + +// Defined in extension_set_heavy.cc. +// bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, +// const MessageLite* containing_type, +// UnknownFieldSet* unknown_fields) + +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, + const MessageLite* containing_type, + FieldSkipper* field_skipper) { + while (true) { + uint32 tag = input->ReadTag(); + switch (tag) { + case 0: + return true; + case WireFormatLite::kMessageSetItemStartTag: + if (!ParseMessageSetItem(input, containing_type, field_skipper)) { + return false; + } + break; + default: + if (!ParseField(tag, input, containing_type, field_skipper)) { + return false; + } + break; + } + } +} + +bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, + const MessageLite* containing_type) { + FieldSkipper skipper; + return ParseMessageSet(input, containing_type, &skipper); +} + +// Defined in extension_set_heavy.cc. +// bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, +// const MessageLite* containing_type, +// UnknownFieldSet* unknown_fields); + +bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, + const MessageLite* containing_type, + FieldSkipper* 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. + + // This method parses a group which should contain two fields: + // 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; + + // If we see message data before the type_id, we'll append it to this so + // we can parse it later. This will probably never happen in practice, + // as no MessageSet encoder I know of writes the message before the type ID. + // But, it's technically valid so we should allow it. + // TODO(kenton): Use a Cord instead? Do I care? + string message_data; + + while (true) { + 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); + + if (!message_data.empty()) { + // We saw some message data before the type_id. Have to parse it + // now. + io::CodedInputStream sub_input( + reinterpret_cast(message_data.data()), + message_data.size()); + if (!ParseField(fake_tag, &sub_input, + containing_type, field_skipper)) { + return false; + } + message_data.clear(); + } + + break; + } + + case WireFormatLite::kMessageSetMessageTag: { + if (fake_tag == 0) { + // We haven't seen a type_id yet. Append this data to message_data. + string temp; + uint32 length; + if (!input->ReadVarint32(&length)) return false; + if (!input->ReadString(&temp, length)) return false; + message_data.append(temp); + } else { + // Already saw type_id, so we can parse this directly. + if (!ParseField(fake_tag, input, + containing_type, field_skipper)) { + return false; + } + } + + break; + } + + case WireFormatLite::kMessageSetItemEndTag: { + return true; + } + + default: { + if (!field_skipper->SkipField(input, tag)) return false; + } + } + } +} + void ExtensionSet::SerializeWithCachedSizes( int start_field_number, int end_field_number, io::CodedOutputStream* output) const { @@ -887,6 +989,31 @@ uint8* ExtensionSet::SerializeWithCachedSizesToArray( return target + written_bytes; } +void ExtensionSet::SerializeMessageSetWithCachedSizes( + io::CodedOutputStream* output) const { + map::const_iterator iter; + for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) { + iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output); + } +} + +uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray( + uint8* target) const { + // For now, just create an array output stream around the target and dispatch + // to SerializeWithCachedSizes(). Give the array output stream kint32max + // bytes; we will certainly write less than that. It is up to the caller to + // ensure that the buffer has sufficient space. + int written_bytes; + { + io::ArrayOutputStream array_stream(target, kint32max); + io::CodedOutputStream output_stream(&array_stream); + SerializeMessageSetWithCachedSizes(&output_stream); + written_bytes = output_stream.ByteCount(); + GOOGLE_DCHECK(!output_stream.HadError()); + } + return target + written_bytes; +} + int ExtensionSet::ByteSize() const { int total_size = 0; @@ -898,18 +1025,20 @@ int ExtensionSet::ByteSize() const { return total_size; } -int ExtensionSet::SpaceUsedExcludingSelf() const { - int total_size = - extensions_.size() * sizeof(map::value_type); - for (map::const_iterator iter = extensions_.begin(), - end = extensions_.end(); - iter != end; - ++iter) { - total_size += iter->second.SpaceUsedExcludingSelf(); +int ExtensionSet::MessageSetByteSize() const { + int total_size = 0; + + for (map::const_iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + total_size += iter->second.MessageSetItemByteSize(iter->first); } + return total_size; } +// Defined in extension_set_heavy.cc. +// int ExtensionSet::SpaceUsedExcludingSelf() const + bool ExtensionSet::MaybeNewExtension(int number, Extension** result) { pair::iterator, bool> insert_result = extensions_.insert(make_pair(number, Extension())); @@ -924,7 +1053,7 @@ void ExtensionSet::Extension::Clear() { if (is_repeated) { switch (cpp_type(type)) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ repeated_##LOWERCASE##_value->Clear(); \ break @@ -943,10 +1072,10 @@ void ExtensionSet::Extension::Clear() { } else { if (!is_cleared) { switch (cpp_type(type)) { - case FieldDescriptor::CPPTYPE_STRING: + case WireFormatLite::CPPTYPE_STRING: string_value->clear(); break; - case FieldDescriptor::CPPTYPE_MESSAGE: + case WireFormatLite::CPPTYPE_MESSAGE: message_value->Clear(); break; default: @@ -968,15 +1097,15 @@ void ExtensionSet::Extension::SerializeFieldWithCachedSizes( if (is_packed) { if (cached_size == 0) return; - WireFormat::WriteTag(number, WireFormat::WIRETYPE_LENGTH_DELIMITED, - output); + WireFormatLite::WriteTag(number, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); output->WriteVarint32(cached_size); switch (real_type(type)) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ + case WireFormatLite::TYPE_##UPPERCASE: \ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - WireFormat::Write##CAMELCASE##NoTag( \ + WireFormatLite::Write##CAMELCASE##NoTag( \ repeated_##LOWERCASE##_value->Get(i), output); \ } \ break @@ -997,19 +1126,19 @@ void ExtensionSet::Extension::SerializeFieldWithCachedSizes( HANDLE_TYPE( ENUM, Enum, enum); #undef HANDLE_TYPE - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_BYTES: - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; break; } } else { switch (real_type(type)) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ + case WireFormatLite::TYPE_##UPPERCASE: \ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - WireFormat::Write##CAMELCASE(number, \ + WireFormatLite::Write##CAMELCASE(number, \ repeated_##LOWERCASE##_value->Get(i), output); \ } \ break @@ -1038,8 +1167,8 @@ void ExtensionSet::Extension::SerializeFieldWithCachedSizes( } else if (!is_cleared) { switch (real_type(type)) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - WireFormat::Write##CAMELCASE(number, VALUE, output); \ + case WireFormatLite::TYPE_##UPPERCASE: \ + WireFormatLite::Write##CAMELCASE(number, VALUE, output); \ break HANDLE_TYPE( INT32, Int32, int32_value); @@ -1065,6 +1194,34 @@ void ExtensionSet::Extension::SerializeFieldWithCachedSizes( } } +void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes( + int number, + io::CodedOutputStream* output) const { + if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { + // Not a valid MessageSet extension, but serialize it the normal way. + SerializeFieldWithCachedSizes(number, output); + return; + } + + if (is_cleared) return; + + // Start group. + output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag); + + // Write type ID. + output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag); + output->WriteVarint32(number); + + // Write message. + output->WriteVarint32(WireFormatLite::kMessageSetMessageTag); + + output->WriteVarint32(message_value->GetCachedSize()); + message_value->SerializeWithCachedSizes(output); + + // End group. + output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag); +} + int ExtensionSet::Extension::ByteSize(int number) const { int result = 0; @@ -1072,9 +1229,9 @@ int ExtensionSet::Extension::ByteSize(int number) const { if (is_packed) { switch (real_type(type)) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ + case WireFormatLite::TYPE_##UPPERCASE: \ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - result += WireFormat::CAMELCASE##Size( \ + result += WireFormatLite::CAMELCASE##Size( \ repeated_##LOWERCASE##_value->Get(i)); \ } \ break @@ -1090,8 +1247,8 @@ int ExtensionSet::Extension::ByteSize(int number) const { // Stuff with fixed size. #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - result += WireFormat::k##CAMELCASE##Size * \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += WireFormatLite::k##CAMELCASE##Size * \ repeated_##LOWERCASE##_value->size(); \ break HANDLE_TYPE( FIXED32, Fixed32, uint32); @@ -1103,10 +1260,10 @@ int ExtensionSet::Extension::ByteSize(int number) const { HANDLE_TYPE( BOOL, Bool, bool); #undef HANDLE_TYPE - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_BYTES: - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_BYTES: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed."; break; } @@ -1115,17 +1272,18 @@ int ExtensionSet::Extension::ByteSize(int number) const { if (result > 0) { result += io::CodedOutputStream::VarintSize32(result); result += io::CodedOutputStream::VarintSize32( - WireFormat::MakeTag(number, WireFormat::WIRETYPE_LENGTH_DELIMITED)); + WireFormatLite::MakeTag(number, + WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); } } else { - int tag_size = WireFormat::TagSize(number, real_type(type)); + int tag_size = WireFormatLite::TagSize(number, real_type(type)); switch (real_type(type)) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ + case WireFormatLite::TYPE_##UPPERCASE: \ result += tag_size * repeated_##LOWERCASE##_value->size(); \ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \ - result += WireFormat::CAMELCASE##Size( \ + result += WireFormatLite::CAMELCASE##Size( \ repeated_##LOWERCASE##_value->Get(i)); \ } \ break @@ -1145,8 +1303,8 @@ int ExtensionSet::Extension::ByteSize(int number) const { // Stuff with fixed size. #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - result += (tag_size + WireFormat::k##CAMELCASE##Size) * \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \ repeated_##LOWERCASE##_value->size(); \ break HANDLE_TYPE( FIXED32, Fixed32, uint32); @@ -1160,11 +1318,11 @@ int ExtensionSet::Extension::ByteSize(int number) const { } } } else if (!is_cleared) { - result += WireFormat::TagSize(number, real_type(type)); + result += WireFormatLite::TagSize(number, real_type(type)); switch (real_type(type)) { #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - result += WireFormat::CAMELCASE##Size(LOWERCASE); \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \ break HANDLE_TYPE( INT32, Int32, int32_value); @@ -1182,8 +1340,8 @@ int ExtensionSet::Extension::ByteSize(int number) const { // Stuff with fixed size. #define HANDLE_TYPE(UPPERCASE, CAMELCASE) \ - case FieldDescriptor::TYPE_##UPPERCASE: \ - result += WireFormat::k##CAMELCASE##Size; \ + case WireFormatLite::TYPE_##UPPERCASE: \ + result += WireFormatLite::k##CAMELCASE##Size; \ break HANDLE_TYPE( FIXED32, Fixed32); HANDLE_TYPE( FIXED64, Fixed64); @@ -1199,11 +1357,34 @@ int ExtensionSet::Extension::ByteSize(int number) const { return result; } +int ExtensionSet::Extension::MessageSetItemByteSize(int number) const { + if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) { + // Not a valid MessageSet extension, but compute the byte size for it the + // normal way. + return ByteSize(number); + } + + if (is_cleared) return 0; + + int our_size = WireFormatLite::kMessageSetItemTagsSize; + + // type_id + our_size += io::CodedOutputStream::VarintSize32(number); + + // message + int message_size = message_value->ByteSize(); + + our_size += io::CodedOutputStream::VarintSize32(message_size); + our_size += message_size; + + return our_size; +} + int ExtensionSet::Extension::GetSize() const { GOOGLE_DCHECK(is_repeated); switch (cpp_type(type)) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ return repeated_##LOWERCASE##_value->size() HANDLE_TYPE( INT32, int32); @@ -1227,7 +1408,7 @@ void ExtensionSet::Extension::Free() { if (is_repeated) { switch (cpp_type(type)) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + case WireFormatLite::CPPTYPE_##UPPERCASE: \ delete repeated_##LOWERCASE##_value; \ break @@ -1245,10 +1426,10 @@ void ExtensionSet::Extension::Free() { } } else { switch (cpp_type(type)) { - case FieldDescriptor::CPPTYPE_STRING: + case WireFormatLite::CPPTYPE_STRING: delete string_value; break; - case FieldDescriptor::CPPTYPE_MESSAGE: + case WireFormatLite::CPPTYPE_MESSAGE: delete message_value; break; default: @@ -1257,43 +1438,8 @@ void ExtensionSet::Extension::Free() { } } -int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { - int total_size = 0; - if (is_repeated) { - switch (cpp_type(type)) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ - total_size += sizeof(*repeated_##LOWERCASE##_value) + \ - repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE( UINT32, uint32); - HANDLE_TYPE( UINT64, uint64); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( DOUBLE, double); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, enum); - HANDLE_TYPE( STRING, string); - HANDLE_TYPE(MESSAGE, message); - } - } else { - switch (cpp_type(type)) { - case FieldDescriptor::CPPTYPE_STRING: - total_size += sizeof(*string_value) + - StringSpaceUsedExcludingSelf(*string_value); - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - total_size += message_value->SpaceUsed(); - break; - default: - // No extra storage costs for primitive types. - break; - } - } - return total_size; -} +// Defined in extension_set_heavy.cc. +// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const } // namespace internal } // namespace protobuf -- cgit v1.2.3