From f157a5651c79a7a36e242af216a5d5b383ba8af2 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Fri, 14 Nov 2014 11:50:31 -0800 Subject: Down-integrate from internal code base (C++ maps support). --- .../protobuf/generated_message_reflection.cc | 185 +++++++++++++++++---- 1 file changed, 152 insertions(+), 33 deletions(-) (limited to 'src/google/protobuf/generated_message_reflection.cc') diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index ea97aebc..a20e362c 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -34,13 +34,16 @@ #include #include + +#include #include -#include #include -#include #include +#include #include -#include +#include +#include + #define GOOGLE_PROTOBUF_HAS_ONEOF @@ -48,6 +51,12 @@ namespace google { namespace protobuf { namespace internal { +namespace { +bool IsMapFieldInApi(const FieldDescriptor* field) { + return field->is_map(); +} +} // anonymous namespace + int StringSpaceUsedExcludingSelf(const string& str) { const void* start = &str; const void* end = &str + 1; @@ -76,14 +85,7 @@ const string& NameOfEnum(const EnumDescriptor* descriptor, int value) { namespace { inline bool SupportsArenas(const Descriptor* descriptor) { - // In open-source release we enable arena support by default but as we also - // down-integrate descriptor.pb.(h|cc) from our internal code base which - // hasn't enabled arena support yet, here we need to be able to handle both - // cases for descriptor protos. - if (!Arena::is_arena_constructable::type::value) { - return descriptor->name() != "google/protobuf/descriptor.proto"; - } - return true; + return descriptor->file()->options().cc_enable_arenas(); } } // anonymous namespace @@ -318,11 +320,17 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const { break; case FieldDescriptor::CPPTYPE_MESSAGE: - // We don't know which subclass of RepeatedPtrFieldBase the type is, - // so we use RepeatedPtrFieldBase directly. - total_size += - GetRaw(message, field) - .SpaceUsedExcludingSelf >(); + if (IsMapFieldInApi(field)) { + total_size += + GetRaw(message, field).SpaceUsedExcludingSelf(); + } else { + // We don't know which subclass of RepeatedPtrFieldBase the type is, + // so we use RepeatedPtrFieldBase directly. + total_size += + GetRaw(message, field) + .SpaceUsedExcludingSelf >(); + } + break; } } else { @@ -406,9 +414,17 @@ void GeneratedMessageReflection::SwapField( case FieldDescriptor::CPPTYPE_STRING: case FieldDescriptor::CPPTYPE_MESSAGE: - MutableRaw(message1, field)-> + if (IsMapFieldInApi(field)) { + MutableRaw(message1, field)-> + MutableRepeatedField()-> + Swap >( + MutableRaw(message2, field)-> + MutableRepeatedField()); + } else { + MutableRaw(message1, field)-> Swap >( MutableRaw(message2, field)); + } break; default: @@ -728,7 +744,11 @@ int GeneratedMessageReflection::FieldSize(const Message& message, case FieldDescriptor::CPPTYPE_STRING: case FieldDescriptor::CPPTYPE_MESSAGE: - return GetRaw(message, field).size(); + if (IsMapFieldInApi(field)) { + return GetRaw(message, field).GetRepeatedField().size(); + } else { + return GetRaw(message, field).size(); + } } GOOGLE_LOG(FATAL) << "Can't get here."; @@ -820,10 +840,16 @@ void GeneratedMessageReflection::ClearField( } case FieldDescriptor::CPPTYPE_MESSAGE: { - // We don't know which subclass of RepeatedPtrFieldBase the type is, - // so we use RepeatedPtrFieldBase directly. - MutableRaw(message, field) - ->Clear >(); + if (IsMapFieldInApi(field)) { + MutableRaw(message, field) + ->MutableRepeatedField() + ->Clear >(); + } else { + // We don't know which subclass of RepeatedPtrFieldBase the type is, + // so we use RepeatedPtrFieldBase directly. + MutableRaw(message, field) + ->Clear >(); + } break; } } @@ -865,8 +891,14 @@ void GeneratedMessageReflection::RemoveLast( break; case FieldDescriptor::CPPTYPE_MESSAGE: - MutableRaw(message, field) + if (IsMapFieldInApi(field)) { + MutableRaw(message, field) + ->MutableRepeatedField() + ->RemoveLast >(); + } else { + MutableRaw(message, field) ->RemoveLast >(); + } break; } } @@ -881,8 +913,14 @@ Message* GeneratedMessageReflection::ReleaseLast( return static_cast( MutableExtensionSet(message)->ReleaseLast(field->number())); } else { - return MutableRaw(message, field) + if (IsMapFieldInApi(field)) { + return MutableRaw(message, field) + ->MutableRepeatedField() + ->ReleaseLast >(); + } else { + return MutableRaw(message, field) ->ReleaseLast >(); + } } } @@ -916,8 +954,14 @@ void GeneratedMessageReflection::SwapElements( case FieldDescriptor::CPPTYPE_STRING: case FieldDescriptor::CPPTYPE_MESSAGE: - MutableRaw(message, field) + if (IsMapFieldInApi(field)) { + MutableRaw(message, field) + ->MutableRepeatedField() + ->SwapElements(index1, index2); + } else { + MutableRaw(message, field) ->SwapElements(index1, index2); + } break; } } @@ -1519,8 +1563,14 @@ const Message& GeneratedMessageReflection::GetRepeatedMessage( return static_cast( GetExtensionSet(message).GetRepeatedMessage(field->number(), index)); } else { - return GetRaw(message, field) - .Get >(index); + if (IsMapFieldInApi(field)) { + return GetRaw(message, field) + .GetRepeatedField() + .Get >(index); + } else { + return GetRaw(message, field) + .Get >(index); + } } } @@ -1533,8 +1583,14 @@ Message* GeneratedMessageReflection::MutableRepeatedMessage( MutableExtensionSet(message)->MutableRepeatedMessage( field->number(), index)); } else { - return MutableRaw(message, field) + if (IsMapFieldInApi(field)) { + return MutableRaw(message, field) + ->MutableRepeatedField() + ->Mutable >(index); + } else { + return MutableRaw(message, field) ->Mutable >(index); + } } } @@ -1549,11 +1605,18 @@ Message* GeneratedMessageReflection::AddMessage( return static_cast( MutableExtensionSet(message)->AddMessage(field, factory)); } else { + Message* result = NULL; + // We can't use AddField() because RepeatedPtrFieldBase doesn't // know how to allocate one. - RepeatedPtrFieldBase* repeated = - MutableRaw(message, field); - Message* result = repeated->AddFromCleared >(); + RepeatedPtrFieldBase* repeated = NULL; + if (IsMapFieldInApi(field)) { + repeated = + MutableRaw(message, field)->MutableRepeatedField(); + } else { + repeated = MutableRaw(message, field); + } + result = repeated->AddFromCleared >(); if (result == NULL) { // We must allocate a new object. const Message* prototype; @@ -1568,6 +1631,7 @@ Message* GeneratedMessageReflection::AddMessage( // of AddAllocated. repeated->UnsafeArenaAddAllocated >(result); } + return result; } } @@ -1584,11 +1648,18 @@ void* GeneratedMessageReflection::MutableRawRepeatedField( GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch"; if (desc != NULL) GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type"; - if (field->is_extension()) + if (field->is_extension()) { return MutableExtensionSet(message)->MutableRawRepeatedField( field->number(), field->type(), field->is_packed(), field); - else + } else { + // Trigger transform for MapField + if (IsMapFieldInApi(field)) { + return reinterpret_cast(reinterpret_cast(message) + + offsets_[field->index()]) + ->MutableRepeatedField(); + } return reinterpret_cast(message) + offsets_[field->index()]; + } } const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor( @@ -2000,6 +2071,54 @@ void* GeneratedMessageReflection::RepeatedFieldData( } } +GeneratedMessageReflection* +GeneratedMessageReflection::NewGeneratedMessageReflection( + const Descriptor* descriptor, + const Message* default_instance, + const int offsets[], + int has_bits_offset, + int unknown_fields_offset, + int extensions_offset, + const void* default_oneof_instance, + int oneof_case_offset, + int object_size, + int arena_offset) { + return new GeneratedMessageReflection(descriptor, + default_instance, + offsets, + has_bits_offset, + unknown_fields_offset, + extensions_offset, + default_oneof_instance, + oneof_case_offset, + DescriptorPool::generated_pool(), + MessageFactory::generated_factory(), + object_size, + arena_offset); +} + +GeneratedMessageReflection* +GeneratedMessageReflection::NewGeneratedMessageReflection( + const Descriptor* descriptor, + const Message* default_instance, + const int offsets[], + int has_bits_offset, + int unknown_fields_offset, + int extensions_offset, + int object_size, + int arena_offset) { + return new GeneratedMessageReflection(descriptor, + default_instance, + offsets, + has_bits_offset, + unknown_fields_offset, + extensions_offset, + DescriptorPool::generated_pool(), + MessageFactory::generated_factory(), + object_size, + arena_offset); +} + } // namespace internal } // namespace protobuf } // namespace google -- cgit v1.2.3