From 0400cca3236de1ca303af38bf81eab332d042b7c Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Tue, 13 Mar 2018 16:37:29 -0700 Subject: Integrated internal changes from Google --- .../protobuf/generated_message_reflection.cc | 67 ++++++++++++++++++++-- 1 file changed, 61 insertions(+), 6 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 b0c975b4..247f772c 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -290,6 +291,13 @@ size_t GeneratedMessageReflection::SpaceUsedLong(const Message& message) const { switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { + if (IsInlined(field)) { + const string* ptr = + &GetField(message, field).GetNoArena(); + total_size += StringSpaceUsedExcludingSelfLong(*ptr); + break; + } + // Initially, the string points to the default value stored in // the prototype. Only count the string if it has been changed // from the default value. @@ -424,15 +432,25 @@ void GeneratedMessageReflection::SwapField( { Arena* arena1 = GetArena(message1); Arena* arena2 = GetArena(message2); + + if (IsInlined(field)) { + InlinedStringField* string1 = + MutableRaw(message1, field); + InlinedStringField* string2 = + MutableRaw(message2, field); + string1->Swap(string2); + break; + } + ArenaStringPtr* string1 = MutableRaw(message1, field); ArenaStringPtr* string2 = MutableRaw(message2, field); + const string* default_ptr = + &DefaultRaw(field).Get(); if (arena1 == arena2) { - string1->Swap(string2); + string1->Swap(string2, default_ptr, arena1); } else { - const string* default_ptr = - &DefaultRaw(field).Get(); const string temp = string1->Get(); string1->Set(default_ptr, string2->Get(), arena1); string2->Set(default_ptr, temp, arena2); @@ -738,7 +756,15 @@ int GeneratedMessageReflection::FieldSize(const Message& message, case FieldDescriptor::CPPTYPE_STRING: case FieldDescriptor::CPPTYPE_MESSAGE: if (IsMapFieldInApi(field)) { - return GetRaw(message, field).GetRepeatedField().size(); + const internal::MapFieldBase& map = + GetRaw(message, field); + if (map.IsRepeatedFieldValid()) { + return map.GetRepeatedField().size(); + } else { + // No need to materialize the repeated field if it is out of sync: + // its size will be the same as the map's size. + return map.size(); + } } else { return GetRaw(message, field).size(); } @@ -789,6 +815,14 @@ void GeneratedMessageReflection::ClearField( switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { + if (IsInlined(field)) { + const string* default_ptr = + &DefaultRaw(field).GetNoArena(); + MutableRaw(message, field)->SetNoArena( + default_ptr, *default_ptr); + break; + } + const string* default_ptr = &DefaultRaw(field).Get(); MutableRaw(message, field)->SetAllocated( @@ -1121,6 +1155,10 @@ string GeneratedMessageReflection::GetString( switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { + if (IsInlined(field)) { + return GetField(message, field).GetNoArena(); + } + return GetField(message, field).Get(); } } @@ -1138,6 +1176,10 @@ const string& GeneratedMessageReflection::GetStringReference( switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { + if (IsInlined(field)) { + return GetField(message, field).GetNoArena(); + } + return GetField(message, field).Get(); } } @@ -1156,6 +1198,12 @@ void GeneratedMessageReflection::SetString( switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { + if (IsInlined(field)) { + MutableField(message, field)->SetNoArena( + NULL, value); + break; + } + const string* default_ptr = &DefaultRaw(field).Get(); if (field->containing_oneof() && !HasOneofField(*message, field)) { ClearOneof(message, field->containing_oneof()); @@ -1868,6 +1916,10 @@ const Type& GeneratedMessageReflection::GetRaw( return GetConstRefAtOffset(message, schema_.GetFieldOffset(field)); } +bool GeneratedMessageReflection::IsInlined(const FieldDescriptor* field) const { + return schema_.IsFieldInlined(field); +} + template Type* GeneratedMessageReflection::MutableRaw(Message* message, const FieldDescriptor* field) const { @@ -1963,6 +2015,10 @@ inline bool GeneratedMessageReflection::HasBit( case FieldDescriptor::CPPTYPE_STRING: switch (field->options().ctype()) { default: { + if (IsInlined(field)) { + return !GetField(message, field) + .GetNoArena().empty(); + } return GetField(message, field).Get().size() > 0; } } @@ -2307,7 +2363,6 @@ struct MetadataOwner { void AssignDescriptors( const string& filename, const MigrationSchema* schemas, const Message* const* default_instances_, const uint32* offsets, - MessageFactory* factory, // update the following descriptor arrays. Metadata* file_level_metadata, const EnumDescriptor** file_level_enum_descriptors, @@ -2316,7 +2371,7 @@ void AssignDescriptors( ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(filename); GOOGLE_CHECK(file != NULL); - if (!factory) factory = MessageFactory::generated_factory(); + MessageFactory* factory = MessageFactory::generated_factory(); AssignDescriptorsHelper helper(factory, file_level_metadata, file_level_enum_descriptors, schemas, -- cgit v1.2.3