diff --git a/BUILD b/BUILD index 078f9434e443..a0c93676a02a 100644 --- a/BUILD +++ b/BUILD @@ -135,6 +135,7 @@ cc_library( "src/google/protobuf/arena.cc", "src/google/protobuf/arenastring.cc", "src/google/protobuf/extension_set.cc", + "src/google/protobuf/field_access_listener.cc", "src/google/protobuf/generated_enum_util.cc", "src/google/protobuf/generated_message_table_driven_lite.cc", "src/google/protobuf/generated_message_util.cc", diff --git a/CHANGES.txt b/CHANGES.txt index 3b0a4f053531..1e4cff87c158 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,15 +1,15 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) - Protocol Compiler + C++ + * Introduce FieldAccessListener. * Stop emitting boilerplate {Copy/Merge}From in each ProtoBuf class - * split the accessor annotations according to their operation - * introduce proto message injector - * let proto message injector decide whether to calculate address info based on field descriptor and access type. - * Disable LITE_RUNTIME injector annotations - * move callback and @protoc_insertion_point after internal set of enum fields - * Improve ExtractFieldInfo codegen for string fields with oneof or default value - * Rename MessageInjector to FieldAccessListener - * Change the API of FieldAccessListener to support callbacks for info extraction - * make field_access_injector private + * Fixed some uninitialized variable warnings in generated_message_reflection.cc. + + Kotlin: + * Add extension functions related to ByteString to c.g.protobuf.kotlin. + + Java + * Fixed parser to check that we are at a proper limit when a sub-message has + finished parsing. 2021-05-07 version 3.17.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) PHP diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index 3e9418cbfc5f..d2ab2dea97fc 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -46,6 +46,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\dynamic_message.h" in copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\empty.pb.h" include\google\protobuf\empty.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set.h" include\google\protobuf\extension_set.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\extension_set_inl.h" include\google\protobuf\extension_set_inl.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_access_listener.h" include\google\protobuf\field_access_listener.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_mask.pb.h" include\google\protobuf\field_mask.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_reflection.h" include\google\protobuf\generated_enum_reflection.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_util.h" include\google\protobuf\generated_enum_util.h diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake index 6d325d5dcad4..a3d5979b75bd 100644 --- a/cmake/libprotobuf-lite.cmake +++ b/cmake/libprotobuf-lite.cmake @@ -3,6 +3,7 @@ set(libprotobuf_lite_files ${protobuf_source_dir}/src/google/protobuf/arena.cc ${protobuf_source_dir}/src/google/protobuf/arenastring.cc ${protobuf_source_dir}/src/google/protobuf/extension_set.cc + ${protobuf_source_dir}/src/google/protobuf/field_access_listener.cc ${protobuf_source_dir}/src/google/protobuf/generated_enum_util.cc ${protobuf_source_dir}/src/google/protobuf/generated_message_table_driven_lite.cc ${protobuf_source_dir}/src/google/protobuf/generated_message_util.cc diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake index a5be494fb702..cf548c7b9933 100644 --- a/cmake/libprotobuf.cmake +++ b/cmake/libprotobuf.cmake @@ -65,6 +65,7 @@ set(libprotobuf_includes ${protobuf_source_dir}/src/google/protobuf/duration.pb.h ${protobuf_source_dir}/src/google/protobuf/dynamic_message.h ${protobuf_source_dir}/src/google/protobuf/empty.pb.h + ${protobuf_source_dir}/src/google/protobuf/field_access_listener.h ${protobuf_source_dir}/src/google/protobuf/field_mask.pb.h ${protobuf_source_dir}/src/google/protobuf/generated_message_reflection.h ${protobuf_source_dir}/src/google/protobuf/io/gzip_stream.h diff --git a/conformance/failure_list_java.txt b/conformance/failure_list_java.txt index b29a63f5e430..808e230eba3b 100644 --- a/conformance/failure_list_java.txt +++ b/conformance/failure_list_java.txt @@ -42,7 +42,3 @@ Required.Proto3.JsonInput.Int32FieldPlusSign Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt Required.Proto3.JsonInput.StringFieldNotAString -Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE -Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE -Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE -Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java index 37b986d7a5df..1060c5af2d95 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java @@ -873,6 +873,9 @@ public void readMessage( builder.mergeFrom(this, extensionRegistry); checkLastTagWas(0); --recursionDepth; + if (getBytesUntilLimit() != 0) { + throw InvalidProtocolBufferException.truncatedMessage(); + } popLimit(oldLimit); } @@ -889,6 +892,9 @@ public T readMessage( T result = parser.parsePartialFrom(this, extensionRegistry); checkLastTagWas(0); --recursionDepth; + if (getBytesUntilLimit() != 0) { + throw InvalidProtocolBufferException.truncatedMessage(); + } popLimit(oldLimit); return result; } @@ -1595,6 +1601,9 @@ public void readMessage( builder.mergeFrom(this, extensionRegistry); checkLastTagWas(0); --recursionDepth; + if (getBytesUntilLimit() != 0) { + throw InvalidProtocolBufferException.truncatedMessage(); + } popLimit(oldLimit); } @@ -1611,6 +1620,9 @@ public T readMessage( T result = parser.parsePartialFrom(this, extensionRegistry); checkLastTagWas(0); --recursionDepth; + if (getBytesUntilLimit() != 0) { + throw InvalidProtocolBufferException.truncatedMessage(); + } popLimit(oldLimit); return result; } @@ -2392,6 +2404,9 @@ public void readMessage( builder.mergeFrom(this, extensionRegistry); checkLastTagWas(0); --recursionDepth; + if (getBytesUntilLimit() != 0) { + throw InvalidProtocolBufferException.truncatedMessage(); + } popLimit(oldLimit); } @@ -2408,6 +2423,9 @@ public T readMessage( T result = parser.parsePartialFrom(this, extensionRegistry); checkLastTagWas(0); --recursionDepth; + if (getBytesUntilLimit() != 0) { + throw InvalidProtocolBufferException.truncatedMessage(); + } popLimit(oldLimit); return result; } @@ -3489,6 +3507,9 @@ public void readMessage( builder.mergeFrom(this, extensionRegistry); checkLastTagWas(0); --recursionDepth; + if (getBytesUntilLimit() != 0) { + throw InvalidProtocolBufferException.truncatedMessage(); + } popLimit(oldLimit); } @@ -3505,6 +3526,9 @@ public T readMessage( T result = parser.parsePartialFrom(this, extensionRegistry); checkLastTagWas(0); --recursionDepth; + if (getBytesUntilLimit() != 0) { + throw InvalidProtocolBufferException.truncatedMessage(); + } popLimit(oldLimit); return result; } diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index 55a5f741e0ed..125df32b9ebb 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -1564,12 +1564,17 @@ static int InternalReparentFields( to_release); } - GOOGLE_CHECK_EQ(self->message->GetArena(), new_message->message->GetArena()); - - MessageReflectionFriend::UnsafeShallowSwapFields( - self->message, new_message->message, - std::vector(fields_to_swap.begin(), - fields_to_swap.end())); + if (self->message->GetArena() == new_message->message->GetArena()) { + MessageReflectionFriend::UnsafeShallowSwapFields( + self->message, new_message->message, + std::vector(fields_to_swap.begin(), + fields_to_swap.end())); + } else { + self->message->GetReflection()->SwapFields( + self->message, new_message->message, + std::vector(fields_to_swap.begin(), + fields_to_swap.end())); + } // This might delete the Python message completely if all children were moved. Py_DECREF(self); diff --git a/src/Makefile.am b/src/Makefile.am index 735e3b84149e..692ef2147ea9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -95,6 +95,7 @@ nobase_include_HEADERS = \ google/protobuf/empty.pb.h \ google/protobuf/extension_set.h \ google/protobuf/extension_set_inl.h \ + google/protobuf/field_access_listener.h \ google/protobuf/field_mask.pb.h \ google/protobuf/generated_enum_reflection.h \ google/protobuf/generated_enum_util.h \ @@ -206,6 +207,7 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/arena.cc \ google/protobuf/arenastring.cc \ google/protobuf/extension_set.cc \ + google/protobuf/field_access_listener.cc \ google/protobuf/generated_enum_util.cc \ google/protobuf/generated_message_util.cc \ google/protobuf/generated_message_table_driven_lite.h \ diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index 76be84980cfe..c6dff7b1f3fd 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -215,7 +215,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Any::_InternalSerialize( (void) cached_has_bits; // string type_url = 1; - if (!this->type_url().empty()) { + if (!this->_internal_type_url().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_type_url().data(), static_cast(this->_internal_type_url().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -225,7 +225,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Any::_InternalSerialize( } // bytes value = 2; - if (!this->value().empty()) { + if (!this->_internal_value().empty()) { target = stream->WriteBytesMaybeAliased( 2, this->_internal_value(), target); } @@ -247,14 +247,14 @@ size_t Any::ByteSizeLong() const { (void) cached_has_bits; // string type_url = 1; - if (!this->type_url().empty()) { + if (!this->_internal_type_url().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_type_url()); } // bytes value = 2; - if (!this->value().empty()) { + if (!this->_internal_value().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( this->_internal_value()); @@ -288,10 +288,10 @@ void Any::MergeFrom(const Any& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (!from.type_url().empty()) { + if (!from._internal_type_url().empty()) { _internal_set_type_url(from._internal_type_url()); } - if (!from.value().empty()) { + if (!from._internal_value().empty()) { _internal_set_value(from._internal_value()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index 35deae379569..310ea2b199b3 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -372,7 +372,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Api::_InternalSerialize( (void) cached_has_bits; // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_name().data(), static_cast(this->_internal_name().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -398,7 +398,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Api::_InternalSerialize( } // string version = 4; - if (!this->version().empty()) { + if (!this->_internal_version().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_version().data(), static_cast(this->_internal_version().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -408,7 +408,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Api::_InternalSerialize( } // .google.protobuf.SourceContext source_context = 5; - if (this->has_source_context()) { + if (this->_internal_has_source_context()) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: InternalWriteMessage( @@ -424,7 +424,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Api::_InternalSerialize( } // .google.protobuf.Syntax syntax = 7; - if (this->syntax() != 0) { + if (this->_internal_syntax() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( 7, this->_internal_syntax(), target); @@ -468,28 +468,28 @@ size_t Api::ByteSizeLong() const { } // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_name()); } // string version = 4; - if (!this->version().empty()) { + if (!this->_internal_version().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_version()); } // .google.protobuf.SourceContext source_context = 5; - if (this->has_source_context()) { + if (this->_internal_has_source_context()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( *source_context_); } // .google.protobuf.Syntax syntax = 7; - if (this->syntax() != 0) { + if (this->_internal_syntax() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); } @@ -525,16 +525,16 @@ void Api::MergeFrom(const Api& from) { methods_.MergeFrom(from.methods_); options_.MergeFrom(from.options_); mixins_.MergeFrom(from.mixins_); - if (!from.name().empty()) { + if (!from._internal_name().empty()) { _internal_set_name(from._internal_name()); } - if (!from.version().empty()) { + if (!from._internal_version().empty()) { _internal_set_version(from._internal_version()); } - if (from.has_source_context()) { + if (from._internal_has_source_context()) { _internal_mutable_source_context()->PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(from._internal_source_context()); } - if (from.syntax() != 0) { + if (from._internal_syntax() != 0) { _internal_set_syntax(from._internal_syntax()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -772,7 +772,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Method::_InternalSerialize( (void) cached_has_bits; // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_name().data(), static_cast(this->_internal_name().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -782,7 +782,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Method::_InternalSerialize( } // string request_type_url = 2; - if (!this->request_type_url().empty()) { + if (!this->_internal_request_type_url().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_request_type_url().data(), static_cast(this->_internal_request_type_url().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -792,13 +792,13 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Method::_InternalSerialize( } // bool request_streaming = 3; - if (this->request_streaming() != 0) { + if (this->_internal_request_streaming() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(3, this->_internal_request_streaming(), target); } // string response_type_url = 4; - if (!this->response_type_url().empty()) { + if (!this->_internal_response_type_url().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_response_type_url().data(), static_cast(this->_internal_response_type_url().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -808,7 +808,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Method::_InternalSerialize( } // bool response_streaming = 5; - if (this->response_streaming() != 0) { + if (this->_internal_response_streaming() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(5, this->_internal_response_streaming(), target); } @@ -822,7 +822,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Method::_InternalSerialize( } // .google.protobuf.Syntax syntax = 7; - if (this->syntax() != 0) { + if (this->_internal_syntax() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( 7, this->_internal_syntax(), target); @@ -852,38 +852,38 @@ size_t Method::ByteSizeLong() const { } // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_name()); } // string request_type_url = 2; - if (!this->request_type_url().empty()) { + if (!this->_internal_request_type_url().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_request_type_url()); } // string response_type_url = 4; - if (!this->response_type_url().empty()) { + if (!this->_internal_response_type_url().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_response_type_url()); } // bool request_streaming = 3; - if (this->request_streaming() != 0) { + if (this->_internal_request_streaming() != 0) { total_size += 1 + 1; } // bool response_streaming = 5; - if (this->response_streaming() != 0) { + if (this->_internal_response_streaming() != 0) { total_size += 1 + 1; } // .google.protobuf.Syntax syntax = 7; - if (this->syntax() != 0) { + if (this->_internal_syntax() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); } @@ -917,22 +917,22 @@ void Method::MergeFrom(const Method& from) { (void) cached_has_bits; options_.MergeFrom(from.options_); - if (!from.name().empty()) { + if (!from._internal_name().empty()) { _internal_set_name(from._internal_name()); } - if (!from.request_type_url().empty()) { + if (!from._internal_request_type_url().empty()) { _internal_set_request_type_url(from._internal_request_type_url()); } - if (!from.response_type_url().empty()) { + if (!from._internal_response_type_url().empty()) { _internal_set_response_type_url(from._internal_response_type_url()); } - if (from.request_streaming() != 0) { + if (from._internal_request_streaming() != 0) { _internal_set_request_streaming(from._internal_request_streaming()); } - if (from.response_streaming() != 0) { + if (from._internal_response_streaming() != 0) { _internal_set_response_streaming(from._internal_response_streaming()); } - if (from.syntax() != 0) { + if (from._internal_syntax() != 0) { _internal_set_syntax(from._internal_syntax()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -1106,7 +1106,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Mixin::_InternalSerialize( (void) cached_has_bits; // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_name().data(), static_cast(this->_internal_name().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -1116,7 +1116,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Mixin::_InternalSerialize( } // string root = 2; - if (!this->root().empty()) { + if (!this->_internal_root().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_root().data(), static_cast(this->_internal_root().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -1142,14 +1142,14 @@ size_t Mixin::ByteSizeLong() const { (void) cached_has_bits; // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_name()); } // string root = 2; - if (!this->root().empty()) { + if (!this->_internal_root().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_root()); @@ -1183,10 +1183,10 @@ void Mixin::MergeFrom(const Mixin& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (!from.name().empty()) { + if (!from._internal_name().empty()) { _internal_set_name(from._internal_name()); } - if (!from.root().empty()) { + if (!from._internal_root().empty()) { _internal_set_root(from._internal_root()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index 76ce0ba44fc6..eceebf710582 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -926,9 +926,15 @@ inline PROTOBUF_NAMESPACE_ID::SourceContext* Api::release_source_context() { PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; source_context_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::SourceContext* Api::unsafe_arena_release_source_context() { diff --git a/src/google/protobuf/arenastring.cc b/src/google/protobuf/arenastring.cc index da49325ec1fb..7608b13c7a4c 100644 --- a/src/google/protobuf/arenastring.cc +++ b/src/google/protobuf/arenastring.cc @@ -256,6 +256,24 @@ void ArenaStringPtr::ClearToDefault(const LazyString& default_value, } } +const char* EpsCopyInputStream::ReadArenaString(const char* ptr, + ArenaStringPtr* s, + Arena* arena) { + GOOGLE_DCHECK(arena != nullptr); + + int size = ReadSize(&ptr); + if (!ptr) return nullptr; + + auto str = Arena::Create(arena); + ptr = ReadString(ptr, size, str); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + + TaggedPtr res; + res.Set(str); + s->UnsafeSetTaggedPointer(res); + + return ptr; +} } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc index 949405deeabf..82247ff065f7 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_field.cc @@ -59,6 +59,69 @@ namespace cpp { using internal::WireFormat; +namespace { + +std::string GenerateAnnotation(StringPiece substitute_template_prefix, + StringPiece prepared_template, + StringPiece substitute_template_suffix, + int field_index, StringPiece lambda_args, + StringPiece access_type) { + return strings::Substitute( + StrCat(substitute_template_prefix, prepared_template, + substitute_template_suffix), + field_index, access_type, lambda_args); +} + +std::string GenerateTemplateForOneofString(const FieldDescriptor* descriptor, + StringPiece proto_ns, + StringPiece field_member) { + std::string field_pointer = + descriptor->options().ctype() == google::protobuf::FieldOptions::STRING + ? "$0.GetPointer()" + : "$0"; + + if (descriptor->default_value_string().empty()) { + return strings::Substitute( + StrCat("_internal_has_", + google::protobuf::compiler::cpp::FieldName(descriptor), + "()? _listener_->ExtractFieldInfo(", field_pointer, + "): ::", proto_ns, "::FieldAccessListener::AddressInfo()"), + field_member); + } + + if (descriptor->options().ctype() == google::protobuf::FieldOptions::STRING_PIECE) { + return StrCat("_listener_->ExtractFieldInfo(_internal_", + google::protobuf::compiler::cpp::FieldName(descriptor), "())"); + } + + std::string default_value_pointer = + descriptor->options().ctype() == google::protobuf::FieldOptions::STRING + ? "&$1.get()" + : "&$1"; + return strings::Substitute( + StrCat("_listener_->ExtractFieldInfo(_internal_has_", + google::protobuf::compiler::cpp::FieldName(descriptor), "()? ", + field_pointer, " : ", default_value_pointer, ")"), + field_member, MakeDefaultName(descriptor)); +} + +std::string GenerateTemplateForSingleString(const FieldDescriptor* descriptor, + StringPiece field_member) { + if (descriptor->default_value_string().empty()) { + return strings::Substitute("_listener_->ExtractFieldInfo(&$0)", field_member); + } + + if (descriptor->options().ctype() == google::protobuf::FieldOptions::STRING) { + return strings::Substitute( + "_listener_->ExtractFieldInfo($0.IsDefault(" + "nullptr) ? &$1.get() : $0.GetPointer())", + field_member, MakeDefaultName(descriptor)); + } + + return strings::Substitute("_listener_->ExtractFieldInfo(&$0)", field_member); +} + +} // namespace void AddAccessorAnnotations(const FieldDescriptor* descriptor, const Options& options, @@ -74,6 +137,129 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor, for (size_t i = 0; i < GOOGLE_ARRAYSIZE(kAccessorsAnnotations); ++i) { (*variables)[kAccessorsAnnotations[i]] = ""; } + if (options.annotate_accessor) { + for (size_t i = 0; i < GOOGLE_ARRAYSIZE(kAccessorsAnnotations); ++i) { + (*variables)[kAccessorsAnnotations[i]] = StrCat( + " ", FieldName(descriptor), "_AccessedNoStrip = true;\n"); + } + } + if (!options.inject_field_listener_events) { + return; + } + if (descriptor->file()->options().optimize_for() == + google::protobuf::FileOptions::LITE_RUNTIME) { + return; + } + std::string field_member = (*variables)["field_member"]; + const google::protobuf::OneofDescriptor* oneof_member = + descriptor->real_containing_oneof(); + if (oneof_member) { + field_member = StrCat(oneof_member->name(), "_.", field_member); + } + const std::string proto_ns = (*variables)["proto_ns"]; + std::string lambda_args = "_listener_, this"; + std::string lambda_flat_args = "_listener_, this"; + const std::string substitute_template_prefix = StrCat( + " {\n" + " auto _listener_ = ::", + proto_ns, + "::FieldAccessListener::GetListener();\n" + " if (_listener_) _listener_->OnFieldAccess([$2] { return "); + const std::string substitute_template_suffix = StrCat( + "; }, " + "GetDescriptor()->field($0), " + "::", + proto_ns, + "::FieldAccessListener::FieldAccessType::$1);\n" + " }\n"); + std::string prepared_template; + + // Flat template is needed if the prepared one is introspecting the values + // inside the returned values, for example, for repeated fields and maps. + std::string prepared_flat_template; + std::string prepared_add_template; + // TODO(jianzhouzh): Fix all forward declared messages and deal with the + // weak fields. + if (descriptor->is_repeated() && !descriptor->is_map()) { + if (descriptor->type() != FieldDescriptor::TYPE_MESSAGE && + descriptor->type() != FieldDescriptor::TYPE_GROUP) { + lambda_args = "_listener_, this, index"; + prepared_template = strings::Substitute( + "_listener_->ExtractFieldInfo(&$0.Get(index))", field_member); + prepared_add_template = strings::Substitute( + "_listener_->ExtractFieldInfo(&$0.Get($0.size() - 1))", field_member); + } else { + prepared_template = + StrCat("::", proto_ns, "::FieldAccessListener::AddressInfo()"); + prepared_add_template = + StrCat("::", proto_ns, "::FieldAccessListener::AddressInfo()"); + } + } else if (descriptor->is_map()) { + prepared_template = + StrCat("::", proto_ns, "::FieldAccessListener::AddressInfo()"); + } else if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE && + !descriptor->options().lazy()) { + prepared_template = + StrCat("::", proto_ns, "::FieldAccessListener::AddressInfo()"); + } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { + if (oneof_member) { + prepared_template = GenerateTemplateForOneofString( + descriptor, (*variables)["proto_ns"], field_member); + } else { + prepared_template = + GenerateTemplateForSingleString(descriptor, field_member); + } + } else { + prepared_template = + strings::Substitute("_listener_->ExtractFieldInfo(&$0)", field_member); + } + if (descriptor->is_repeated() && !descriptor->is_map() && + descriptor->type() != FieldDescriptor::TYPE_MESSAGE && + descriptor->type() != FieldDescriptor::TYPE_GROUP) { + prepared_flat_template = + strings::Substitute("_listener_->ExtractFieldInfo(&$0)", field_member); + } else { + prepared_flat_template = prepared_template; + } + (*variables)["annotate_get"] = GenerateAnnotation( + substitute_template_prefix, prepared_template, substitute_template_suffix, + descriptor->index(), lambda_args, "kGet"); + (*variables)["annotate_set"] = GenerateAnnotation( + substitute_template_prefix, prepared_template, substitute_template_suffix, + descriptor->index(), lambda_args, "kSet"); + (*variables)["annotate_has"] = GenerateAnnotation( + substitute_template_prefix, prepared_template, substitute_template_suffix, + descriptor->index(), lambda_args, "kHas"); + (*variables)["annotate_mutable"] = GenerateAnnotation( + substitute_template_prefix, prepared_template, substitute_template_suffix, + descriptor->index(), lambda_args, "kMutable"); + (*variables)["annotate_release"] = GenerateAnnotation( + substitute_template_prefix, prepared_template, substitute_template_suffix, + descriptor->index(), lambda_args, "kRelease"); + (*variables)["annotate_clear"] = + GenerateAnnotation(substitute_template_prefix, prepared_flat_template, + substitute_template_suffix, descriptor->index(), + lambda_flat_args, "kClear"); + (*variables)["annotate_size"] = + GenerateAnnotation(substitute_template_prefix, prepared_flat_template, + substitute_template_suffix, descriptor->index(), + lambda_flat_args, "kSize"); + (*variables)["annotate_list"] = + GenerateAnnotation(substitute_template_prefix, prepared_flat_template, + substitute_template_suffix, descriptor->index(), + lambda_flat_args, "kList"); + (*variables)["annotate_mutable_list"] = + GenerateAnnotation(substitute_template_prefix, prepared_flat_template, + substitute_template_suffix, descriptor->index(), + lambda_flat_args, "kMutableList"); + (*variables)["annotate_add"] = + GenerateAnnotation(substitute_template_prefix, prepared_add_template, + substitute_template_suffix, descriptor->index(), + lambda_flat_args, "kAdd"); + (*variables)["annotate_add_mutable"] = + GenerateAnnotation(substitute_template_prefix, prepared_add_template, + substitute_template_suffix, descriptor->index(), + lambda_flat_args, "kAddMutable"); } void SetCommonFieldVariables(const FieldDescriptor* descriptor, diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 78bacbc8c473..0c239479d403 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -1139,7 +1139,7 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { GOOGLE_CHECK(!options_.opensource_runtime); IncludeFile("net/proto2/public/weak_field_map.h", printer); } - if (HasLazyFields(file_, options_)) { + if (HasLazyFields(file_, options_, &scc_analyzer_)) { GOOGLE_CHECK(!options_.opensource_runtime); IncludeFile("net/proto2/public/lazy_field.h", printer); } diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc index a1cd06d15cf6..2a6087ee4188 100644 --- a/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc @@ -104,6 +104,14 @@ bool CppGenerator::Generate(const FileDescriptor* file, file_options.num_cc_files = strto32(options[i].second.c_str(), NULL, 10); } + } else if (options[i].first == "annotate_accessor") { + file_options.annotate_accessor = true; + } else if (options[i].first == "inject_field_listener_events") { + file_options.inject_field_listener_events = true; + } else if (options[i].first == "eagerly_verified_lazy") { + file_options.eagerly_verified_lazy = true; + } else if (options[i].first == "force_eagerly_verified_lazy") { + file_options.force_eagerly_verified_lazy = true; } else if (options[i].first == "table_driven_parsing") { file_options.table_driven_parsing = true; } else if (options[i].first == "table_driven_serialization") { diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 16ee07448d53..c39c52a8c4f5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -205,9 +205,20 @@ void SetIntVar(const Options& options, const std::string& type, std::map* variables) { (*variables)[type] = IntTypeName(options, type); } +bool IsEagerlyVerifiedLazyImpl(const FieldDescriptor* field, + const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + return false; +} } // namespace +bool IsLazy(const FieldDescriptor* field, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + return IsLazilyVerifiedLazy(field, options) || + IsEagerlyVerifiedLazyImpl(field, options, scc_analyzer); +} + void SetCommonVars(const Options& options, std::map* variables) { (*variables)["proto_ns"] = ProtobufNamespace(options); @@ -785,20 +796,20 @@ std::string SafeFunctionName(const Descriptor* descriptor, return function_name; } -static bool HasLazyFields(const Descriptor* descriptor, - const Options& options) { +static bool HasLazyFields(const Descriptor* descriptor, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { for (int field_idx = 0; field_idx < descriptor->field_count(); field_idx++) { - if (IsLazy(descriptor->field(field_idx), options)) { + if (IsLazy(descriptor->field(field_idx), options, scc_analyzer)) { return true; } } for (int idx = 0; idx < descriptor->extension_count(); idx++) { - if (IsLazy(descriptor->extension(idx), options)) { + if (IsLazy(descriptor->extension(idx), options, scc_analyzer)) { return true; } } for (int idx = 0; idx < descriptor->nested_type_count(); idx++) { - if (HasLazyFields(descriptor->nested_type(idx), options)) { + if (HasLazyFields(descriptor->nested_type(idx), options, scc_analyzer)) { return true; } } @@ -806,15 +817,16 @@ static bool HasLazyFields(const Descriptor* descriptor, } // Does the given FileDescriptor use lazy fields? -bool HasLazyFields(const FileDescriptor* file, const Options& options) { +bool HasLazyFields(const FileDescriptor* file, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { for (int i = 0; i < file->message_type_count(); i++) { const Descriptor* descriptor(file->message_type(i)); - if (HasLazyFields(descriptor, options)) { + if (HasLazyFields(descriptor, options, scc_analyzer)) { return true; } } for (int field_idx = 0; field_idx < file->extension_count(); field_idx++) { - if (IsLazy(file->extension(field_idx), options)) { + if (IsLazy(file->extension(field_idx), options, scc_analyzer)) { return true; } } @@ -1143,6 +1155,9 @@ bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options, MessageAnalysis MessageSCCAnalyzer::GetSCCAnalysis(const SCC* scc) { if (analysis_cache_.count(scc)) return analysis_cache_[scc]; MessageAnalysis result{}; + if (UsingImplicitWeakFields(scc->GetFile(), options_)) { + result.contains_weak = true; + } for (int i = 0; i < scc->descriptors.size(); i++) { const Descriptor* descriptor = scc->descriptors[i]; if (descriptor->extension_range_count() > 0) { @@ -1153,6 +1168,9 @@ MessageAnalysis MessageSCCAnalyzer::GetSCCAnalysis(const SCC* scc) { if (field->is_required()) { result.contains_required = true; } + if (field->options().weak()) { + result.contains_weak = true; + } switch (field->type()) { case FieldDescriptor::TYPE_STRING: case FieldDescriptor::TYPE_BYTES: { @@ -1171,6 +1189,7 @@ MessageAnalysis MessageSCCAnalyzer::GetSCCAnalysis(const SCC* scc) { if (!ShouldIgnoreRequiredFieldCheck(field, options_)) { result.contains_required |= analysis.contains_required; } + result.contains_weak |= analysis.contains_weak; } else { // This field points back into the same SCC hence the messages // in the SCC are recursive. Note if SCC contains more than two diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index d15ac29defb2..247c161ce589 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -331,17 +331,30 @@ inline bool IsStringPiece(const FieldDescriptor* field, EffectiveStringCType(field, options) == FieldOptions::STRING_PIECE; } +class MessageSCCAnalyzer; + // Does the given FileDescriptor use lazy fields? -bool HasLazyFields(const FileDescriptor* file, const Options& options); +bool HasLazyFields(const FileDescriptor* file, const Options& options, + MessageSCCAnalyzer* scc_analyzer); // Is the given field a supported lazy field? -inline bool IsLazy(const FieldDescriptor* field, const Options& options) { +bool IsLazy(const FieldDescriptor* field, const Options& options, + MessageSCCAnalyzer* scc_analyzer); + +inline bool IsLazilyVerifiedLazy(const FieldDescriptor* field, + const Options& options) { return field->options().lazy() && !field->is_repeated() && field->type() == FieldDescriptor::TYPE_MESSAGE && GetOptimizeFor(field->file(), options) != FileOptions::LITE_RUNTIME && !options.opensource_runtime; } +inline bool IsEagerlyVerifiedLazy(const FieldDescriptor* field, + const Options& options, + MessageSCCAnalyzer* scc_analyzer) { + return IsLazy(field, options, scc_analyzer) && !field->options().lazy(); +} + inline bool IsFieldUsed(const FieldDescriptor* /* field */, const Options& options) { return true; @@ -527,8 +540,8 @@ bool HasWeakFields(const FileDescriptor* desc, const Options& options); // given field. inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field, const Options& options) { - // Do not check "required" for lazy fields. - return IsLazy(field, options); + // Do not check "required" for lazily verified lazy fields. + return IsLazilyVerifiedLazy(field, options); } struct MessageAnalysis { @@ -536,6 +549,7 @@ struct MessageAnalysis { bool contains_cord; bool contains_extension; bool contains_required; + bool contains_weak; // Implicit weak as well. }; // This class is used in FileGenerator, to ensure linear instead of @@ -552,6 +566,10 @@ class PROTOC_EXPORT MessageSCCAnalyzer { MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor)); return result.contains_required || result.contains_extension; } + bool HasWeakField(const Descriptor* descriptor) { + MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor)); + return result.contains_weak; + } const SCC* GetSCC(const Descriptor* descriptor) { return analyzer_.GetSCC(descriptor); } diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 68840d57aa20..be6f34810840 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -168,14 +168,16 @@ bool IsPOD(const FieldDescriptor* field) { // Anything that is a POD or a "normal" message (represented by a pointer) can // be manipulated as raw bytes. bool CanBeManipulatedAsRawBytes(const FieldDescriptor* field, - const Options& options) { + const Options& options, + MessageSCCAnalyzer* scc_analyzer) { bool ret = CanInitializeByZeroing(field); // Non-repeated, non-lazy message fields are simply raw pointers, so we can // swap them or use memset to initialize these in SharedCtor. We cannot use // this in Clear, as we need to potentially delete the existing value. - ret = ret || (!field->is_repeated() && !IsLazy(field, options) && - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE); + ret = + ret || (!field->is_repeated() && !IsLazy(field, options, scc_analyzer) && + field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE); return ret; } @@ -218,16 +220,18 @@ bool EmitFieldNonDefaultCondition(io::Printer* printer, // if non-zero (numeric) or non-empty (string). if (!field->is_repeated() && !field->containing_oneof()) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { - format("if (!$prefix$$name$().empty()) {\n"); + format("if (!$prefix$_internal_$name$().empty()) {\n"); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { // Message fields still have has_$name$() methods. - format("if ($prefix$has_$name$()) {\n"); + format("if ($prefix$_internal_has_$name$()) {\n"); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE || field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT) { // Handle float comparison to prevent -Wfloat-equal warnings - format("if (!($prefix$$name$() <= 0 && $prefix$$name$() >= 0)) {\n"); + format( + "if (!($prefix$_internal_$name$() <= 0 && $prefix$_internal_$name$() " + ">= 0)) {\n"); } else { - format("if ($prefix$$name$() != 0) {\n"); + format("if ($prefix$_internal_$name$() != 0) {\n"); } format.Indent(); return true; @@ -313,7 +317,8 @@ bool ShouldSerializeInOrder(const Descriptor* descriptor, } bool TableDrivenParsingEnabled(const Descriptor* descriptor, - const Options& options) { + const Options& options, + MessageSCCAnalyzer* scc_analyzer) { if (!options.table_driven_parsing) { return false; } @@ -344,7 +349,7 @@ bool TableDrivenParsingEnabled(const Descriptor* descriptor, } // - There are no lazy fields (they require the non-lite library). - if (IsLazy(field, options)) { + if (IsLazy(field, options, scc_analyzer)) { return false; } } @@ -579,6 +584,35 @@ MessageGenerator::MessageGenerator( variables_["annotate_reflection"] = ""; variables_["annotate_bytesize"] = ""; + if (options.inject_field_listener_events && + descriptor->file()->options().optimize_for() != + google::protobuf::FileOptions::LITE_RUNTIME) { + const std::string injector_template = StrCat( + " {\n" + " auto _listener_ = ::", + variables_["proto_ns"], + "::FieldAccessListener::GetListener();\n" + " if (_listener_) "); + + StrAppend(&variables_["annotate_serialize"], injector_template, + "_listener_->OnSerializationAccess(this);\n" + " }\n"); + StrAppend(&variables_["annotate_deserialize"], injector_template, + " _listener_->OnDeserializationAccess(this);\n" + " }\n"); + // TODO(danilak): Ideally annotate_reflection should not exist and we need + // to annotate all reflective calls on our own, however, as this is a cause + // for side effects, i.e. reading values dynamically, we want the users know + // that dynamic access can happen. + StrAppend(&variables_["annotate_reflection"], injector_template, + "_listener_->OnReflectionAccess(default_instance()" + ".GetMetadata().descriptor);\n" + " }\n"); + StrAppend(&variables_["annotate_bytesize"], injector_template, + "_listener_->OnByteSizeAccess(this);\n" + " }\n"); + } + SetUnknownFieldsVariable(descriptor_, options_, &variables_); // Compute optimized field order to be used for layout and initialization @@ -595,7 +629,8 @@ MessageGenerator::MessageGenerator( } } - message_layout_helper_->OptimizeLayout(&optimized_order_, options_); + message_layout_helper_->OptimizeLayout(&optimized_order_, options_, + scc_analyzer_); // This message has hasbits iff one or more fields need one. for (auto field : optimized_order_) { @@ -618,7 +653,8 @@ MessageGenerator::MessageGenerator( } } - table_driven_ = TableDrivenParsingEnabled(descriptor_, options_); + table_driven_ = + TableDrivenParsingEnabled(descriptor_, options_, scc_analyzer_); parse_function_generator_.reset(new ParseFunctionGenerator( descriptor_, max_has_bit_index_, has_bit_indices_, options_, scc_analyzer_, variables_)); @@ -794,7 +830,7 @@ void MessageGenerator::GenerateSingularFieldHasBits( "(_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"); if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !IsLazy(field, options_)) { + !IsLazy(field, options_, scc_analyzer_)) { // We maintain the invariant that for a submessage x, has_x() returning // true implies that x_ is not null. By giving this information to the // compiler, we allow it to eliminate unnecessary null checks later on. @@ -810,7 +846,7 @@ void MessageGenerator::GenerateSingularFieldHasBits( "}\n"); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { // Message fields have a has_$name$() method. - if (IsLazy(field, options_)) { + if (IsLazy(field, options_, scc_analyzer_)) { format( "inline bool $classname$::_internal_has_$name$() const {\n" " return !$name$_.IsCleared();\n" @@ -1853,7 +1889,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { const FieldGenerator& generator = field_generators_.get(field); int type = CalcFieldNum(generator, field, options_); - if (IsLazy(field, options_)) { + if (IsLazy(field, options_, scc_analyzer_)) { type = internal::FieldMetadata::kSpecial; ptr = "reinterpret_cast(::" + variables_["proto_ns"] + "::internal::LazyFieldSerializer"; @@ -2311,6 +2347,8 @@ std::pair MessageGenerator::GenerateOffsets( if (!IsFieldUsed(field, options_)) { format(" | 0x80000000u, // unused\n"); + } else if (IsEagerlyVerifiedLazy(field, options_, scc_analyzer_)) { + format(" | 0x1u, // eagerly verified lazy\n"); } else { format(",\n"); } @@ -2486,7 +2524,7 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer, optimized_order_, [copy_constructor, this](const FieldDescriptor* field) { return (copy_constructor && IsPOD(field)) || (!copy_constructor && - CanBeManipulatedAsRawBytes(field, options_)); + CanBeManipulatedAsRawBytes(field, options_, scc_analyzer_)); }); std::string pod_template; @@ -2554,7 +2592,8 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { GOOGLE_DCHECK(!IsFieldStripped(field, options_)); bool has_arena_constructor = field->is_repeated(); if (!field->real_containing_oneof() && - (IsLazy(field, options_) || IsStringPiece(field, options_))) { + (IsLazy(field, options_, scc_analyzer_) || + IsStringPiece(field, options_))) { has_arena_constructor = true; } if (has_arena_constructor) { @@ -2961,7 +3000,7 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { // If possible, we swap several fields at once, including padding. const RunMap runs = FindRuns(optimized_order_, [this](const FieldDescriptor* field) { - return CanBeManipulatedAsRawBytes(field, options_); + return CanBeManipulatedAsRawBytes(field, options_, scc_analyzer_); }); for (int i = 0; i < optimized_order_.size(); ++i) { @@ -4018,6 +4057,13 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { } } else if (field->options().weak()) { continue; + } else if (IsEagerlyVerifiedLazy(field, options_, scc_analyzer_)) { + GOOGLE_CHECK(!field->real_containing_oneof()); + format( + "if (_internal_has_$1$()) {\n" + " if (!$1$().IsInitialized()) return false;\n" + "}\n", + FieldName(field)); } else { GOOGLE_CHECK(!field->real_containing_oneof()); format( diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index c04c83ad6749..ee677ea4f0ba 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -200,9 +200,15 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( " $clear_hasbit$\n" " $type$* temp = $casted_member$;\n" " $name$_ = nullptr;\n" + "#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE\n" + " auto* old = reinterpret_cast<::$proto_ns$::MessageLite*>(temp);\n" + " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" + " if (GetArenaForAllocation() == nullptr) { delete old; }\n" + "#else // PROTOBUF_FORCE_COPY_IN_RELEASE\n" " if (GetArenaForAllocation() != nullptr) {\n" " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" " }\n" + "#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE\n" " return temp;\n" "}\n" "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h b/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h index 67eeff0ae730..9d8063d9cab3 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h +++ b/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h @@ -43,6 +43,8 @@ namespace protobuf { namespace compiler { namespace cpp { +class MessageSCCAnalyzer; + // Provides an abstract interface to optimize message layout // by rearranging the fields of a message. class MessageLayoutHelper { @@ -50,7 +52,8 @@ class MessageLayoutHelper { virtual ~MessageLayoutHelper() {} virtual void OptimizeLayout(std::vector* fields, - const Options& options) = 0; + const Options& options, + MessageSCCAnalyzer* scc_analyzer) = 0; }; } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h index 04142eeb927a..2e97c3dde065 100644 --- a/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/src/google/protobuf/compiler/cpp/cpp_options.h @@ -75,6 +75,8 @@ struct Options { kTCTableAlways } tctable_mode = kTCTableNever; bool inject_field_listener_events = false; + bool eagerly_verified_lazy = false; + bool force_eagerly_verified_lazy = false; }; } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc index 2f78bda520d2..0b660c75b7b3 100644 --- a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc +++ b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc @@ -118,7 +118,8 @@ class FieldGroup { // // OTHER these fields are initialized one-by-one. void PaddingOptimizer::OptimizeLayout( - std::vector* fields, const Options& options) { + std::vector* fields, const Options& options, + MessageSCCAnalyzer* scc_analyzer) { // The sorted numeric order of Family determines the declaration order in the // memory layout. enum Family { @@ -147,7 +148,7 @@ void PaddingOptimizer::OptimizeLayout( f = STRING; } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { f = MESSAGE; - if (IsLazy(field, options)) { + if (IsLazy(field, options, scc_analyzer)) { f = LAZY_MESSAGE; } } else if (CanInitializeByZeroing(field)) { diff --git a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h index 2382081babb1..ebdb17de61f5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h +++ b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h @@ -53,7 +53,8 @@ class PaddingOptimizer : public MessageLayoutHelper { ~PaddingOptimizer() override {} void OptimizeLayout(std::vector* fields, - const Options& options) override; + const Options& options, + MessageSCCAnalyzer* scc_analyzer) override; }; } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc index aa9500b776db..6886b4f2c31f 100644 --- a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc @@ -94,8 +94,8 @@ std::string MessageParseFunctionName(const FieldDescriptor* field, } else { name.append("Singular"); } - name.append("ParseMessage<" + ClassName(field->message_type()) + ", " + - TagType(field) + ">"); + name.append("ParseMessage<" + QualifiedClassName(field->message_type()) + + ", " + TagType(field) + ">"); return name; } @@ -198,9 +198,23 @@ TailCallTableInfo::TailCallTableInfo(const Descriptor* descriptor, case FieldDescriptor::TYPE_SFIXED32: case FieldDescriptor::TYPE_DOUBLE: case FieldDescriptor::TYPE_FLOAT: + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_UINT32: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_SINT32: + case FieldDescriptor::TYPE_BOOL: name = FieldParseFunctionName(field, options, table_size_log2); break; + case FieldDescriptor::TYPE_BYTES: + if (field->options().ctype() == FieldOptions::STRING && + field->default_value_string().empty()) { + name = FieldParseFunctionName(field, options, table_size_log2); + } + break; + default: break; } @@ -263,10 +277,10 @@ void ParseFunctionGenerator::GenerateMethodDecls(io::Printer* printer) { if (tc_table_info_->use_generated_fallback) { format( "static const char* Tct_ParseFallback(\n" - " ::google::protobuf::MessageLite *msg, const char *ptr,\n" - " ::google::protobuf::internal::ParseContext *ctx,\n" - " const ::google::protobuf::internal::TailCallParseTableBase *table,\n" - " uint64_t hasbits, ::google::protobuf::internal::TcFieldData data);\n" + " ::$proto_ns$::MessageLite *msg, const char *ptr,\n" + " ::$proto_ns$::internal::ParseContext *ctx,\n" + " const ::$proto_ns$::internal::TailCallParseTableBase *table,\n" + " uint64_t hasbits, ::$proto_ns$::internal::TcFieldData data);\n" "inline const char* Tct_FallbackImpl(\n" " const char* ptr, ::$proto_ns$::internal::ParseContext* ctx,\n" " const void*, $uint64$ hasbits);\n"); @@ -646,7 +660,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, } else { format("ptr = ctx->ParseMessage(&$1$_, ptr);\n", FieldName(field)); } - } else if (IsLazy(field, options_)) { + } else if (IsLazy(field, options_, scc_analyzer_)) { if (field->real_containing_oneof()) { format( "if (!_internal_has_$1$()) {\n" @@ -988,7 +1002,22 @@ std::string FieldParseFunctionName(const FieldDescriptor* field, break; case FieldDescriptor::TYPE_STRING: - type_format = TypeFormat::kString; + switch (GetUtf8CheckMode(field, options)) { + case Utf8CheckMode::kNone: + type_format = TypeFormat::kBytes; + break; + case Utf8CheckMode::kStrict: + type_format = TypeFormat::kString; + break; + case Utf8CheckMode::kVerify: + type_format = TypeFormat::kStringValidateOnly; + break; + default: + GOOGLE_LOG(DFATAL) + << "Mode not handled: " + << static_cast(GetUtf8CheckMode(field, options)); + return ""; + } break; default: @@ -998,7 +1027,7 @@ std::string FieldParseFunctionName(const FieldDescriptor* field, return "::" + ProtobufNamespace(options) + "::internal::" + GetTailCallFieldHandlerName(card, type_format, table_size_log2, - TagSize(field->number())); + TagSize(field->number()), options); } } // namespace @@ -1006,7 +1035,8 @@ std::string FieldParseFunctionName(const FieldDescriptor* field, std::string GetTailCallFieldHandlerName(ParseCardinality card, TypeFormat type_format, int table_size_log2, - int tag_length_bytes) { + int tag_length_bytes, + const Options& options) { std::string name; switch (card) { @@ -1056,6 +1086,20 @@ std::string GetTailCallFieldHandlerName(ParseCardinality card, name.append("Fixed"); break; + case TypeFormat::kVar64: + case TypeFormat::kVar32: + case TypeFormat::kSInt64: + case TypeFormat::kSInt32: + case TypeFormat::kBool: + name.append("Varint"); + break; + + case TypeFormat::kBytes: + case TypeFormat::kString: + case TypeFormat::kStringValidateOnly: + name.append("String"); + break; + default: break; } @@ -1067,35 +1111,59 @@ std::string GetTailCallFieldHandlerName(ParseCardinality card, switch (type_format) { case TypeFormat::kVar64: case TypeFormat::kFixed64: - name.append("uint64_t"); + name.append("uint64_t, "); break; case TypeFormat::kSInt64: - name.append("int64_t"); + name.append("int64_t, "); break; case TypeFormat::kVar32: case TypeFormat::kFixed32: - name.append("uint32_t"); + name.append("uint32_t, "); break; case TypeFormat::kSInt32: - name.append("int32_t"); + name.append("int32_t, "); break; case TypeFormat::kBool: - name.append("bool"); + name.append("bool, "); break; default: - GOOGLE_LOG(FATAL) << static_cast(type_format); - return ""; + break; } - name.append(", "); name.append(CodedTagType(tag_length_bytes)); + std::string tcpb = + StrCat(ProtobufNamespace(options), "::internal::TcParserBase"); + switch (type_format) { + case TypeFormat::kVar64: + case TypeFormat::kVar32: + case TypeFormat::kBool: + name.append(StrCat(", ::", tcpb, "::kNoConversion")); + break; + + case TypeFormat::kSInt64: + case TypeFormat::kSInt32: + name.append(StrCat(", ::", tcpb, "::kZigZag")); + break; + + case TypeFormat::kBytes: + name.append(StrCat(", ::", tcpb, "::kNoUtf8")); + break; + + case TypeFormat::kString: + name.append(StrCat(", ::", tcpb, "::kUtf8")); + break; + + case TypeFormat::kStringValidateOnly: + name.append(StrCat(", ::", tcpb, "::kUtf8ValidateOnly")); + break; + default: break; } diff --git a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h index 00719a8f1344..116353af347a 100644 --- a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h +++ b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.h @@ -169,7 +169,8 @@ enum class TypeFormat { std::string GetTailCallFieldHandlerName(ParseCardinality card, TypeFormat type_format, int table_size_log2, - int tag_length_bytes); + int tag_length_bytes, + const Options& options); } // namespace cpp } // namespace compiler diff --git a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto index 479710821fbb..466a84194af0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto +++ b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto @@ -41,7 +41,7 @@ syntax = "proto2"; // Some generic_services option(s) added automatically. // See: http://go/proto2-generic-services-default -option cc_generic_services = true; // auto-added +option cc_generic_services = true; // auto-added // We don't put this in a package within proto2 because we need to make sure // that the generated code doesn't depend on being in the proto2 namespace. @@ -158,11 +158,11 @@ message TestConflictingEnumNames { // NO_PROTO3 optional while conflicting_enum = 1; // NO_PROTO3 } // NO_PROTO3 -enum bool { // NO_PROTO3 - default = 0; // NO_PROTO3 - NOT_EQ = 1; // NO_PROTO3 - volatile = 2; // NO_PROTO3 - return = 3; // NO_PROTO3 +enum bool { // NO_PROTO3 + default = 0; // NO_PROTO3 + NOT_EQ = 1; // NO_PROTO3 + volatile = 2; // NO_PROTO3 + return = 3; // NO_PROTO3 } // NO_PROTO3 message DummyMessage {} @@ -173,7 +173,7 @@ message NULL { extend TestConflictingSymbolNames { // NO_PROTO3 optional int32 void = 314253; // NO_PROTO3 -} // NO_PROTO3 +} // NO_PROTO3 // Message names that could conflict. message Shutdown {} diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 4207bc476448..be6a92a17dd1 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -1337,9 +1337,15 @@ inline PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::release_c _has_bits_[0] &= ~0x00000002u; PROTOBUF_NAMESPACE_ID::compiler::Version* temp = compiler_version_; compiler_version_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::unsafe_arena_release_compiler_version() { @@ -1595,9 +1601,15 @@ inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::rel _has_bits_[0] &= ~0x00000008u; PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = generated_code_info_; generated_code_info_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::unsafe_arena_release_generated_code_info() { diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 40ded3a1eb17..bedb5b38c3f7 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -786,13 +786,7 @@ class FileDescriptorTables { mutable internal::WrappedMutex unknown_enum_values_mu_; }; -DescriptorPool::Tables::Tables() - // Start some hash-map and hash-set objects with a small # of buckets - : known_bad_files_(3), - known_bad_symbols_(3), - extensions_loaded_from_db_(3), - symbols_by_name_(3), - files_by_name_(3) { +DescriptorPool::Tables::Tables() { well_known_types_.insert({ {"google.protobuf.DoubleValue", Descriptor::WELLKNOWNTYPE_DOUBLEVALUE}, {"google.protobuf.FloatValue", Descriptor::WELLKNOWNTYPE_FLOATVALUE}, @@ -816,16 +810,8 @@ DescriptorPool::Tables::Tables() DescriptorPool::Tables::~Tables() { GOOGLE_DCHECK(checkpoints_.empty()); } FileDescriptorTables::FileDescriptorTables() - // Initialize all the hash tables to start out with a small # of buckets. - : symbols_by_parent_(3), - fields_by_lowercase_name_(3), - fields_by_lowercase_name_tmp_(new FieldsByNameMap()), - fields_by_camelcase_name_(3), - fields_by_camelcase_name_tmp_(new FieldsByNameMap()), - fields_by_number_(3), - enum_values_by_number_(3), - unknown_enum_values_by_number_(3), - locations_by_path_(3) {} + : fields_by_lowercase_name_tmp_(new FieldsByNameMap()), + fields_by_camelcase_name_tmp_(new FieldsByNameMap()) {} FileDescriptorTables::~FileDescriptorTables() {} diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index c490863f3ecc..347a03dbc9ca 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -7113,9 +7113,15 @@ inline PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::release_options( _has_bits_[0] &= ~0x00000008u; PROTOBUF_NAMESPACE_ID::FileOptions* temp = options_; options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::unsafe_arena_release_options() { @@ -7197,9 +7203,15 @@ inline PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::release_sourc _has_bits_[0] &= ~0x00000010u; PROTOBUF_NAMESPACE_ID::SourceCodeInfo* temp = source_code_info_; source_code_info_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::unsafe_arena_release_source_code_info() { @@ -7399,9 +7411,15 @@ inline PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRa _has_bits_[0] &= ~0x00000001u; PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* temp = options_; options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::unsafe_arena_release_options() { @@ -7845,9 +7863,15 @@ inline PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::release_options() _has_bits_[0] &= ~0x00000002u; PROTOBUF_NAMESPACE_ID::MessageOptions* temp = options_; options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::unsafe_arena_release_options() { @@ -8496,9 +8520,15 @@ inline PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::release_option _has_bits_[0] &= ~0x00000020u; PROTOBUF_NAMESPACE_ID::FieldOptions* temp = options_; options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::unsafe_arena_release_options() { @@ -8670,9 +8700,15 @@ inline PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::release_option _has_bits_[0] &= ~0x00000002u; PROTOBUF_NAMESPACE_ID::OneofOptions* temp = options_; options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::unsafe_arena_release_options() { @@ -8916,9 +8952,15 @@ inline PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::release_options( _has_bits_[0] &= ~0x00000002u; PROTOBUF_NAMESPACE_ID::EnumOptions* temp = options_; options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::unsafe_arena_release_options() { @@ -9205,9 +9247,15 @@ inline PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::releas _has_bits_[0] &= ~0x00000002u; PROTOBUF_NAMESPACE_ID::EnumValueOptions* temp = options_; options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::unsafe_arena_release_options() { @@ -9391,9 +9439,15 @@ inline PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::release_op _has_bits_[0] &= ~0x00000002u; PROTOBUF_NAMESPACE_ID::ServiceOptions* temp = options_; options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::unsafe_arena_release_options() { @@ -9653,9 +9707,15 @@ inline PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::release_opti _has_bits_[0] &= ~0x00000008u; PROTOBUF_NAMESPACE_ID::MethodOptions* temp = options_; options_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::unsafe_arena_release_options() { diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index d889cc169c81..13fc338475fa 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc @@ -189,13 +189,13 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Duration::_InternalSerialize( (void) cached_has_bits; // int64 seconds = 1; - if (this->seconds() != 0) { + if (this->_internal_seconds() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(1, this->_internal_seconds(), target); } // int32 nanos = 2; - if (this->nanos() != 0) { + if (this->_internal_nanos() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_nanos(), target); } @@ -217,14 +217,14 @@ size_t Duration::ByteSizeLong() const { (void) cached_has_bits; // int64 seconds = 1; - if (this->seconds() != 0) { + if (this->_internal_seconds() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( this->_internal_seconds()); } // int32 nanos = 2; - if (this->nanos() != 0) { + if (this->_internal_nanos() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( this->_internal_nanos()); @@ -258,10 +258,10 @@ void Duration::MergeFrom(const Duration& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (from.seconds() != 0) { + if (from._internal_seconds() != 0) { _internal_set_seconds(from._internal_seconds()); } - if (from.nanos() != 0) { + if (from._internal_nanos() != 0) { _internal_set_nanos(from._internal_nanos()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); diff --git a/src/google/protobuf/field_access_listener.cc b/src/google/protobuf/field_access_listener.cc new file mode 100644 index 000000000000..56e175a7ac6c --- /dev/null +++ b/src/google/protobuf/field_access_listener.cc @@ -0,0 +1,52 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// 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 +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include + +namespace google { +namespace protobuf { + +internal::once_flag FieldAccessListener::register_once_ = {}; +FieldAccessListener* FieldAccessListener::field_listener_ = nullptr; + +FieldAccessListener* FieldAccessListener::GetListener() { + return field_listener_; +} + +void FieldAccessListener::RegisterListener(FieldAccessListener* listener) { + // TODO(danilak): Add a GOOGLE_DCHECK for message_injector_ to be nullptr and update + // tests. + internal::call_once(register_once_, [&] { field_listener_ = listener; }); +} + +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/field_access_listener.h b/src/google/protobuf/field_access_listener.h new file mode 100644 index 000000000000..660ad73a8a2d --- /dev/null +++ b/src/google/protobuf/field_access_listener.h @@ -0,0 +1,246 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// 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 +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__ +#define GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace internal { +template +struct ResolvedType { + using type = T; +}; +} // namespace internal +// Tracks the events of field accesses for all protos +// that are built with --inject_field_listener_events. This is a global +// interface which you must implement yourself and register with +// RegisterListener() function. All events consist of Descriptors, +// FieldAccessTypes and the underlying storage for tracking the memory which is +// accessed where possible and makes sense. Users are responsible for the +// implementations to be thread safe. +class FieldAccessListener { + public: + FieldAccessListener() = default; + virtual ~FieldAccessListener() = default; + + // The memory annotations of the proto fields that are touched by the + // accessors. They are returned as if the operation completes. + struct DataAnnotation { + DataAnnotation() = default; + DataAnnotation(const void* other_address, size_t other_size) + : address(other_address), size(other_size) {} + const void* address = nullptr; + size_t size = 0; + }; + using AddressInfo = std::vector; + using AddressInfoExtractor = std::function; + + enum class FieldAccessType { + kAdd, // add_(f) + kAddMutable, // add_() + kGet, // () and (i) + kClear, // clear_() + kHas, // has_() + kList, // () + kMutable, // mutable_() + kMutableList, // mutable_() + kRelease, // release_() + kSet, // set_() and set_(i) + kSize, // _size() + }; + + static FieldAccessListener* GetListener(); + + // Registers the field listener, can be called only once, |listener| must + // outlive all proto accesses (in most cases, the lifetime of the program). + static void RegisterListener(FieldAccessListener* listener); + + // All field accessors noted in FieldAccessType have this call. + // |extractor| extracts the address info from the field + virtual void OnFieldAccess(const AddressInfoExtractor& extractor, + const FieldDescriptor* descriptor, + FieldAccessType access_type) = 0; + + // Side effect calls. + virtual void OnDeserializationAccess(const Message* message) = 0; + virtual void OnSerializationAccess(const Message* message) = 0; + virtual void OnReflectionAccess(const Descriptor* descriptor) = 0; + virtual void OnByteSizeAccess(const Message* message) = 0; + // We can probably add more if we need to, like {Merge,Copy}{From}Access. + + // Extracts all the addresses from the underlying fields. + template + AddressInfo ExtractFieldInfo(const T* field_value); + + + private: + template + AddressInfo ExtractFieldInfoSpecific(const T* field_value, + internal::ResolvedType); + + AddressInfo ExtractFieldInfoSpecific(const Message* field_value, + internal::ResolvedType); + + AddressInfo ExtractFieldInfoSpecific(const std::string* field_value, + internal::ResolvedType); + + AddressInfo ExtractFieldInfoSpecific( + const internal::ArenaStringPtr* field_value, + internal::ResolvedType); + + template + AddressInfo ExtractFieldInfoSpecific( + const RepeatedField* field_value, + internal::ResolvedType>); + + template + AddressInfo ExtractFieldInfoSpecific( + const RepeatedPtrField* field_value, + internal::ResolvedType>); + + template + AddressInfo ExtractFieldInfoSpecific(const Map* field_value, + internal::ResolvedType>); + + static internal::once_flag register_once_; + static FieldAccessListener* field_listener_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldAccessListener); +}; + +template +inline FieldAccessListener::AddressInfo FieldAccessListener::ExtractFieldInfo( + const T* field_value) { + return ExtractFieldInfoSpecific(field_value, internal::ResolvedType()); +} + + +template +inline FieldAccessListener::AddressInfo +FieldAccessListener::ExtractFieldInfoSpecific(const T* field_value, + internal::ResolvedType) { + static_assert(std::is_trivial::value, + "This overload should be chosen only for trivial types"); + return FieldAccessListener::AddressInfo{FieldAccessListener::DataAnnotation( + static_cast(field_value), sizeof(*field_value))}; +} + +inline FieldAccessListener::AddressInfo +FieldAccessListener::ExtractFieldInfoSpecific( + const std::string* field_value, internal::ResolvedType) { + return FieldAccessListener::AddressInfo{FieldAccessListener::DataAnnotation( + static_cast(field_value->c_str()), field_value->length())}; +} + +inline FieldAccessListener::AddressInfo +FieldAccessListener::ExtractFieldInfoSpecific( + const internal::ArenaStringPtr* field_value, + internal::ResolvedType) { + return FieldAccessListener::ExtractFieldInfoSpecific( + field_value->GetPointer(), internal::ResolvedType()); +} + +template +inline FieldAccessListener::AddressInfo +FieldAccessListener::ExtractFieldInfoSpecific( + const RepeatedField* field_value, + internal::ResolvedType>) { + // TODO(jianzhouzh): This can cause data races. Synchronize this if needed. + FieldAccessListener::AddressInfo address_info; + address_info.reserve(field_value->size()); + for (int i = 0, ie = field_value->size(); i < ie; ++i) { + auto sub = ExtractFieldInfoSpecific(&field_value->Get(i), + internal::ResolvedType()); + address_info.insert(address_info.end(), sub.begin(), sub.end()); + } + return address_info; +} + +template +inline FieldAccessListener::AddressInfo +FieldAccessListener::ExtractFieldInfoSpecific( + const RepeatedPtrField* field_value, + internal::ResolvedType>) { + FieldAccessListener::AddressInfo address_info; + // TODO(jianzhouzh): This can cause data races. Synchronize this if needed. + address_info.reserve(field_value->size()); + for (int i = 0, ie = field_value->size(); i < ie; ++i) { + auto sub = ExtractFieldInfoSpecific(&field_value->Get(i), + internal::ResolvedType()); + address_info.insert(address_info.end(), sub.begin(), sub.end()); + } + return address_info; +} + +template +inline FieldAccessListener::AddressInfo +FieldAccessListener::ExtractFieldInfoSpecific( + const Map* field_value, internal::ResolvedType>) { + // TODO(jianzhouzh): This can cause data races. Synchronize this if needed. + FieldAccessListener::AddressInfo address_info; + address_info.reserve(field_value->size()); + for (auto it = field_value->begin(); it != field_value->end(); ++it) { + auto sub_first = + ExtractFieldInfoSpecific(&it->first, internal::ResolvedType()); + auto sub_second = + ExtractFieldInfoSpecific(&it->second, internal::ResolvedType()); + address_info.insert(address_info.end(), sub_first.begin(), sub_first.end()); + address_info.insert(address_info.end(), sub_second.begin(), + sub_second.end()); + } + return address_info; +} + +inline FieldAccessListener::AddressInfo +FieldAccessListener::ExtractFieldInfoSpecific(const Message* field_value, + internal::ResolvedType) { + // TODO(jianzhouzh): implement and adjust all annotations in the compiler. + return {}; +} + +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__ diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index e743dd11e4fe..f50352f2ce1a 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -76,6 +76,17 @@ namespace protobuf { namespace { bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); } + +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE +Message* MaybeForceCopy(Arena* arena, Message* msg) { + if (arena != nullptr || msg == nullptr) return msg; + + Message* copy = msg->New(); + copy->MergeFrom(*msg); + delete msg; + return copy; +} +#endif // PROTOBUF_FORCE_COPY_IN_RELEASE } // anonymous namespace namespace internal { @@ -512,13 +523,13 @@ void SwapFieldHelper::SwapMessage(const Reflection* r, Message* lhs, if (*lhs_sub != nullptr && *rhs_sub != nullptr) { (*lhs_sub)->GetReflection()->Swap(*lhs_sub, *rhs_sub); - } else if (*lhs_sub == nullptr) { + } else if (*lhs_sub == nullptr && r->HasBit(*rhs, field)) { *lhs_sub = (*rhs_sub)->New(lhs_arena); (*lhs_sub)->CopyFrom(**rhs_sub); r->ClearField(rhs, field); // Ensures has bit is unchanged after ClearField. r->SetBit(rhs, field); - } else { + } else if (*rhs_sub == nullptr && r->HasBit(*lhs, field)) { *rhs_sub = (*lhs_sub)->New(rhs_arena); (*rhs_sub)->CopyFrom(**lhs_sub); r->ClearField(lhs, field); @@ -649,14 +660,14 @@ void Reflection::SwapOneofField(Message* message1, Message* message2, uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor); uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor); - int32 temp_int32; - int64 temp_int64; - uint32 temp_uint32; - uint64 temp_uint64; - float temp_float; - double temp_double; - bool temp_bool; - int temp_int; + int32 temp_int32 = 0; + int64 temp_int64 = 0; + uint32 temp_uint32 = 0; + uint64 temp_uint64 = 0; + float temp_float = 0; + double temp_double = 0; + bool temp_bool = false; + int temp_int = 0; Message* temp_message = nullptr; std::string temp_string; @@ -1196,19 +1207,25 @@ Message* Reflection::ReleaseLast(Message* message, USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE); CheckInvalidAccess(schema_, field); + Message* released; if (field->is_extension()) { - return static_cast( + released = static_cast( MutableExtensionSet(message)->ReleaseLast(field->number())); } else { if (IsMapFieldInApi(field)) { - return MutableRaw(message, field) - ->MutableRepeatedField() - ->ReleaseLast >(); + released = MutableRaw(message, field) + ->MutableRepeatedField() + ->ReleaseLast>(); } else { - return MutableRaw(message, field) - ->ReleaseLast >(); + released = MutableRaw(message, field) + ->ReleaseLast>(); } } +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + return MaybeForceCopy(message->GetArenaForAllocation(), released); +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + return released; +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE } void Reflection::SwapElements(Message* message, const FieldDescriptor* field, @@ -1918,6 +1935,9 @@ Message* Reflection::ReleaseMessage(Message* message, CheckInvalidAccess(schema_, field); Message* released = UnsafeArenaReleaseMessage(message, field, factory); +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + released = MaybeForceCopy(message->GetArenaForAllocation(), released); +#endif // PROTOBUF_FORCE_COPY_IN_RELEASE if (message->GetArenaForAllocation() != nullptr && released != nullptr) { Message* copy_from_arena = released->New(); copy_from_arena->CopyFrom(*released); diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc index d5c68db61fdc..0b6ed8e4addc 100644 --- a/src/google/protobuf/generated_message_reflection_unittest.cc +++ b/src/google/protobuf/generated_message_reflection_unittest.cc @@ -200,6 +200,38 @@ TEST(GeneratedMessageReflectionTest, SwapWithBothSet) { EXPECT_EQ(532819, message2.optional_int32()); } +TEST(GeneratedMessageReflectionTest, SwapWithLhsCleared) { + unittest::TestAllTypes message1; + unittest::TestAllTypes message2; + + TestUtil::SetAllFields(&message1); + + // For proto2 message, for message field, Clear only reset hasbits, but + // doesn't delete the underlying field. + message1.Clear(); + + const Reflection* reflection = message1.GetReflection(); + reflection->Swap(&message1, &message2); + + TestUtil::ExpectClear(message2); +} + +TEST(GeneratedMessageReflectionTest, SwapWithRhsCleared) { + unittest::TestAllTypes message1; + unittest::TestAllTypes message2; + + TestUtil::SetAllFields(&message2); + + // For proto2 message, for message field, Clear only reset hasbits, but + // doesn't delete the underlying field. + message2.Clear(); + + const Reflection* reflection = message1.GetReflection(); + reflection->Swap(&message1, &message2); + + TestUtil::ExpectClear(message1); +} + TEST(GeneratedMessageReflectionTest, SwapExtensions) { unittest::TestAllExtensions message1; unittest::TestAllExtensions message2; diff --git a/src/google/protobuf/generated_message_tctable_impl.h b/src/google/protobuf/generated_message_tctable_impl.h index b4cf9291b926..07879bdcbe57 100644 --- a/src/google/protobuf/generated_message_tctable_impl.h +++ b/src/google/protobuf/generated_message_tctable_impl.h @@ -79,7 +79,7 @@ class TcParserBase { return table->fallback(PROTOBUF_TC_PARAM_PASS); } ptr += sizeof(TagType); - hasbits |= (1 << data.hasbit_idx()); + hasbits |= (uint64_t{1} << data.hasbit_idx()); auto& field = RefAt(msg, data.offset()); if (field == nullptr) { auto arena = ctx->data().arena; @@ -111,6 +111,18 @@ class TcParserBase { template static const char* PackedFixed(PROTOBUF_TC_PARAM_DECL); + enum VarintDecode { kNoConversion = 0, kZigZag = 1 }; + template + static const char* RepeatedVarint(PROTOBUF_TC_PARAM_DECL); + template + static const char* PackedVarint(PROTOBUF_TC_PARAM_DECL); + + enum Utf8Type { kNoUtf8 = 0, kUtf8 = 1, kUtf8ValidateOnly = 2 }; + template + static const char* SingularString(PROTOBUF_TC_PARAM_DECL); + template + static const char* RepeatedString(PROTOBUF_TC_PARAM_DECL); + protected: template static T& RefAt(void* x, size_t offset) { @@ -231,6 +243,9 @@ struct TcParser final : TcParserBase { template static const char* SingularFixed(PROTOBUF_TC_PARAM_DECL); + + template + static const char* SingularVarint(PROTOBUF_TC_PARAM_DECL); }; // Declare helper functions: diff --git a/src/google/protobuf/generated_message_tctable_impl.inc b/src/google/protobuf/generated_message_tctable_impl.inc index 2e3dbf271146..e6e5dd515e05 100644 --- a/src/google/protobuf/generated_message_tctable_impl.inc +++ b/src/google/protobuf/generated_message_tctable_impl.inc @@ -44,6 +44,47 @@ template const char* TcParser<4>::SingularFixed(PROTOBUF_TC_P template const char* TcParser<5>::SingularFixed(PROTOBUF_TC_PARAM_DECL); template const char* TcParserBase::RepeatedFixed(PROTOBUF_TC_PARAM_DECL); template const char* TcParserBase::PackedFixed(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL); template const char* TcParser<1>::SingularFixed(PROTOBUF_TC_PARAM_DECL); template const char* TcParser<2>::SingularFixed(PROTOBUF_TC_PARAM_DECL); template const char* TcParser<3>::SingularFixed(PROTOBUF_TC_PARAM_DECL); @@ -58,6 +99,47 @@ template const char* TcParser<4>::SingularFixed(PROTOBUF_TC_ template const char* TcParser<5>::SingularFixed(PROTOBUF_TC_PARAM_DECL); template const char* TcParserBase::RepeatedFixed(PROTOBUF_TC_PARAM_DECL); template const char* TcParserBase::PackedFixed(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL); +template const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL); #else extern template const char* TcParser<1>::SingularFixed(PROTOBUF_TC_PARAM_DECL); extern template const char* TcParser<2>::SingularFixed(PROTOBUF_TC_PARAM_DECL); @@ -73,6 +155,47 @@ extern template const char* TcParser<4>::SingularFixed(PROTOB extern template const char* TcParser<5>::SingularFixed(PROTOBUF_TC_PARAM_DECL); extern template const char* TcParserBase::RepeatedFixed(PROTOBUF_TC_PARAM_DECL); extern template const char* TcParserBase::PackedFixed(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL); extern template const char* TcParser<1>::SingularFixed(PROTOBUF_TC_PARAM_DECL); extern template const char* TcParser<2>::SingularFixed(PROTOBUF_TC_PARAM_DECL); extern template const char* TcParser<3>::SingularFixed(PROTOBUF_TC_PARAM_DECL); @@ -87,5 +210,46 @@ extern template const char* TcParser<4>::SingularFixed(PROTO extern template const char* TcParser<5>::SingularFixed(PROTOBUF_TC_PARAM_DECL); extern template const char* TcParserBase::RepeatedFixed(PROTOBUF_TC_PARAM_DECL); extern template const char* TcParserBase::PackedFixed(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<1>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<2>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<3>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<4>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParser<5>::SingularVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::PackedVarint(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL); +extern template const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL); #endif // clang-format on diff --git a/src/google/protobuf/generated_message_tctable_lite.cc b/src/google/protobuf/generated_message_tctable_lite.cc index 9eb5d5a31e72..f8a09f4e8ebc 100644 --- a/src/google/protobuf/generated_message_tctable_lite.cc +++ b/src/google/protobuf/generated_message_tctable_lite.cc @@ -77,7 +77,7 @@ const char* TcParser::SingularFixed(PROTOBUF_TC_PARAM_DECL) { return table->fallback(PROTOBUF_TC_PARAM_PASS); } ptr += sizeof(TagType); // Consume tag - hasbits |= (1 << data.hasbit_idx()); + hasbits |= (uint64_t{1} << data.hasbit_idx()); std::memcpy(Offset(msg, data.offset()), ptr, sizeof(LayoutType)); ptr += sizeof(LayoutType); // TailCall syncs any pending hasbits: @@ -140,6 +140,300 @@ const char* TcParserBase::PackedFixed(PROTOBUF_TC_PARAM_DECL) { static_cast*>(&field)); } +////////////////////////////////////////////////////////////////////////////// +// Varint fields +////////////////////////////////////////////////////////////////////////////// + +namespace { + +inline PROTOBUF_ALWAYS_INLINE std::pair +Parse64FallbackPair(const char* p, int64_t res1) { + auto ptr = reinterpret_cast(p); + + // The algorithm relies on sign extension for each byte to set all high bits + // when the varint continues. It also relies on asserting all of the lower + // bits for each successive byte read. This allows the result to be aggregated + // using a bitwise AND. For example: + // + // 8 1 64 57 ... 24 17 16 9 8 1 + // ptr[0] = 1aaa aaaa ; res1 = 1111 1111 ... 1111 1111 1111 1111 1aaa aaaa + // ptr[1] = 1bbb bbbb ; res2 = 1111 1111 ... 1111 1111 11bb bbbb b111 1111 + // ptr[2] = 1ccc cccc ; res3 = 0000 0000 ... 000c cccc cc11 1111 1111 1111 + // --------------------------------------------- + // res1 & res2 & res3 = 0000 0000 ... 000c cccc ccbb bbbb baaa aaaa + // + // On x86-64, a shld from a single register filled with enough 1s in the high + // bits can accomplish all this in one instruction. It so happens that res1 + // has 57 high bits of ones, which is enough for the largest shift done. + GOOGLE_DCHECK_EQ(res1 >> 7, -1); + uint64_t ones = res1; // save the high 1 bits from res1 (input to SHLD) + uint64_t byte; // the "next" 7-bit chunk, shifted (result from SHLD) + int64_t res2, res3; // accumulated result chunks +#define SHLD(n) byte = ((byte << (n * 7)) | (ones >> (64 - (n * 7)))) + + int sign_bit; +#if defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(__x86_64__) + // For the first two rounds (ptr[1] and ptr[2]), micro benchmarks show a + // substantial improvement from capturing the sign from the condition code + // register on x86-64. +#define SHLD_SIGN(n) \ + asm("shldq %3, %2, %1" \ + : "=@ccs"(sign_bit), "+r"(byte) \ + : "r"(ones), "i"(n * 7)) +#else + // Generic fallback: +#define SHLD_SIGN(n) \ + do { \ + SHLD(n); \ + sign_bit = static_cast(byte) < 0; \ + } while (0) +#endif + + byte = ptr[1]; + SHLD_SIGN(1); + res2 = byte; + if (!sign_bit) goto done2; + byte = ptr[2]; + SHLD_SIGN(2); + res3 = byte; + if (!sign_bit) goto done3; + +#undef SHLD_SIGN + + // For the remainder of the chunks, check the sign of the AND result. + byte = ptr[3]; + SHLD(3); + res1 &= byte; + if (res1 >= 0) goto done4; + byte = ptr[4]; + SHLD(4); + res2 &= byte; + if (res2 >= 0) goto done5; + byte = ptr[5]; + SHLD(5); + res3 &= byte; + if (res3 >= 0) goto done6; + byte = ptr[6]; + SHLD(6); + res1 &= byte; + if (res1 >= 0) goto done7; + byte = ptr[7]; + SHLD(7); + res2 &= byte; + if (res2 >= 0) goto done8; + byte = ptr[8]; + SHLD(8); + res3 &= byte; + if (res3 >= 0) goto done9; + +#undef SHLD + + // For valid 64bit varints, the 10th byte/ptr[9] should be exactly 1. In this + // case, the continuation bit of ptr[8] already set the top bit of res3 + // correctly, so all we have to do is check that the expected case is true. + byte = ptr[9]; + if (PROTOBUF_PREDICT_TRUE(byte == 1)) goto done10; + + // A value of 0, however, represents an over-serialized varint. This case + // should not happen, but if does (say, due to a nonconforming serializer), + // deassert the continuation bit that came from ptr[8]. + if (byte == 0) { + res3 ^= static_cast(1) << 63; + goto done10; + } + + // If the 10th byte/ptr[9] itself has any other value, then it is too big to + // fit in 64 bits. If the continue bit is set, it is an unterminated varint. + return {nullptr, 0}; + +#define DONE(n) done##n : return {p + n, res1 & res2 & res3}; +done2: + return {p + 2, res1 & res2}; + DONE(3) + DONE(4) + DONE(5) + DONE(6) + DONE(7) + DONE(8) + DONE(9) + DONE(10) +#undef DONE +} + +inline PROTOBUF_ALWAYS_INLINE const char* ParseVarint(const char* p, + uint64_t* value) { + int64_t byte = static_cast(*p); + if (PROTOBUF_PREDICT_TRUE(byte >= 0)) { + *value = byte; + return p + 1; + } else { + auto tmp = Parse64FallbackPair(p, byte); + if (PROTOBUF_PREDICT_TRUE(tmp.first)) *value = tmp.second; + return tmp.first; + } +} + +} // namespace + +template +template +const char* TcParser::SingularVarint(PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(static_cast(data.coded_tag()) != 0)) { + return table->fallback(PROTOBUF_TC_PARAM_PASS); + } + ptr += sizeof(TagType); // Consume tag + hasbits |= (uint64_t{1} << data.hasbit_idx()); + uint64_t tmp; + ptr = ParseVarint(ptr, &tmp); + if (ptr == nullptr) { + return Error(PROTOBUF_TC_PARAM_PASS); + } + RefAt(msg, data.offset()) = static_cast( + zigzag ? google::protobuf::internal::WireFormatLite::ZigZagDecode64(tmp) : tmp); + PROTOBUF_MUSTTAIL return TailCall(PROTOBUF_TC_PARAM_PASS); +} + +template +PROTOBUF_NOINLINE const char* TcParserBase::RepeatedVarint( + PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(static_cast(data.coded_tag()) != 0)) { + // Try parsing as non-packed repeated: + InvertPacked(data); + if (static_cast(data.coded_tag()) == 0) { + return PackedVarint(PROTOBUF_TC_PARAM_PASS); + } else { + return table->fallback(PROTOBUF_TC_PARAM_PASS); + } + } + auto& field = RefAt>(msg, data.offset()); + auto expected_tag = UnalignedLoad(ptr); + do { + ptr += sizeof(TagType); + uint64_t tmp; + ptr = ParseVarint(ptr, &tmp); + if (ptr == nullptr) { + return Error(PROTOBUF_TC_PARAM_PASS); + } + field.Add(zigzag ? google::protobuf::internal::WireFormatLite::ZigZagDecode64(tmp) + : tmp); + if (!ctx->DataAvailable(ptr)) { + break; + } + } while (UnalignedLoad(ptr) == expected_tag); + return Return(PROTOBUF_TC_PARAM_PASS); +} + +template +PROTOBUF_NOINLINE const char* TcParserBase::PackedVarint( + PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(static_cast(data.coded_tag()) != 0)) { + InvertPacked(data); + if (static_cast(data.coded_tag()) == 0) { + return RepeatedVarint(PROTOBUF_TC_PARAM_PASS); + } else { + return table->fallback(PROTOBUF_TC_PARAM_PASS); + } + } + ptr += sizeof(TagType); + // Since ctx->ReadPackedVarint does not use TailCall or Return, sync any + // pending hasbits now: + SyncHasbits(msg, hasbits, table); + auto* field = &RefAt>(msg, data.offset()); + return ctx->ReadPackedVarint(ptr, [field](uint64_t varint) { + FieldType val; + if (zigzag) { + if (sizeof(FieldType) == 8) { + val = WireFormatLite::ZigZagDecode64(varint); + } else { + val = WireFormatLite::ZigZagDecode32(varint); + } + } else { + val = varint; + } + field->Add(val); + }); +} + +////////////////////////////////////////////////////////////////////////////// +// String/bytes fields +////////////////////////////////////////////////////////////////////////////// + +// Defined in wire_format_lite.cc +void PrintUTF8ErrorLog(const char* field_name, const char* operation_str, + bool emit_stacktrace); + +namespace { + +PROTOBUF_NOINLINE +const char* SingularStringParserFallback(ArenaStringPtr* s, const char* ptr, + EpsCopyInputStream* stream) { + int size = ReadSize(&ptr); + if (!ptr) return nullptr; + return stream->ReadString( + ptr, size, s->MutableNoArenaNoDefault(&GetEmptyStringAlreadyInited())); +} + +} // namespace + +template +const char* TcParserBase::SingularString(PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(static_cast(data.coded_tag()) != 0)) { + return table->fallback(PROTOBUF_TC_PARAM_PASS); + } + ptr += sizeof(TagType); + hasbits |= (uint64_t{1} << data.hasbit_idx()); + auto& field = RefAt(msg, data.offset()); + auto arena = ctx->data().arena; + if (arena) { + ptr = ctx->ReadArenaString(ptr, &field, arena); + } else { + ptr = SingularStringParserFallback(&field, ptr, ctx); + } + if (ptr == nullptr) return Error(PROTOBUF_TC_PARAM_PASS); + switch (utf8) { + case kNoUtf8: +#ifdef NDEBUG + case kUtf8ValidateOnly: +#endif + return Return(PROTOBUF_TC_PARAM_PASS); + default: + if (PROTOBUF_PREDICT_TRUE(IsStructurallyValidUTF8(field.Get()))) { + return Return(PROTOBUF_TC_PARAM_PASS); + } + PrintUTF8ErrorLog("unknown", "parsing", false); + return utf8 == kUtf8 ? Error(PROTOBUF_TC_PARAM_PASS) + : Return(PROTOBUF_TC_PARAM_PASS); + } +} + +template +const char* TcParserBase::RepeatedString(PROTOBUF_TC_PARAM_DECL) { + if (PROTOBUF_PREDICT_FALSE(static_cast(data.coded_tag()) != 0)) { + return table->fallback(PROTOBUF_TC_PARAM_PASS); + } + auto expected_tag = UnalignedLoad(ptr); + auto& field = RefAt>(msg, data.offset()); + do { + ptr += sizeof(TagType); + std::string* str = field.Add(); + ptr = InlineGreedyStringParser(str, ptr, ctx); + if (ptr == nullptr) { + return Error(PROTOBUF_TC_PARAM_PASS); + } + if (utf8 != kNoUtf8) { + if (PROTOBUF_PREDICT_FALSE(!IsStructurallyValidUTF8(*str))) { + PrintUTF8ErrorLog("unknown", "parsing", false); + if (utf8 == kUtf8) return Error(PROTOBUF_TC_PARAM_PASS); + } + } + if (!ctx->DataAvailable(ptr)) break; + } while (UnalignedLoad(ptr) == expected_tag); + return Return(PROTOBUF_TC_PARAM_PASS); +} + #define PROTOBUF_TCT_SOURCE #include diff --git a/src/google/protobuf/parse_context.h b/src/google/protobuf/parse_context.h index 14748f665976..d858191a888d 100644 --- a/src/google/protobuf/parse_context.h +++ b/src/google/protobuf/parse_context.h @@ -166,6 +166,10 @@ class PROTOBUF_EXPORT EpsCopyInputStream { } return AppendStringFallback(ptr, size, s); } + // Implemented in arenastring.cc + PROTOBUF_MUST_USE_RESULT const char* ReadArenaString(const char* ptr, + ArenaStringPtr* s, + Arena* arena); template PROTOBUF_MUST_USE_RESULT const char* ReadRepeatedFixed(const char* ptr, diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index 10a609b36b4f..55012521703c 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -183,7 +183,8 @@ #ifdef PROTOBUF_TAILCALL #error PROTOBUF_TAILCALL was previously defined #endif -#if __has_cpp_attribute(clang::musttail) && !defined(_ARCH_PPC) +#if __has_cpp_attribute(clang::musttail) && \ + !defined(_ARCH_PPC) && !defined(__wasm__) # ifndef PROTO2_OPENSOURCE // Compilation fails on powerpc64le: b/187985113 # endif @@ -408,6 +409,14 @@ #endif # define PROTOBUF_MUST_USE_RESULT +#ifdef PROTOBUF_MUST_USE_EXTRACT_RESULT +#error PROTOBUF_MUST_USE_EXTRACT_RESULT was previously defined +#endif + +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE +#error PROTOBUF_FORCE_COPY_IN_RELEASE was previously defined +#endif + #ifdef PROTOBUF_FORCE_COPY_IN_SWAP #error PROTOBUF_FORCE_COPY_IN_SWAP was previously defined #endif diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index 470547e31fa8..4e956d4ed15f 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -61,6 +61,8 @@ #undef PROTOBUF_EXPORT #undef PROTOC_EXPORT #undef PROTOBUF_MUST_USE_RESULT +#undef PROTOBUF_MUST_USE_EXTRACT_RESULT +#undef PROTOBUF_FORCE_COPY_IN_RELEASE #undef PROTOBUF_FORCE_COPY_IN_SWAP #undef PROTOBUF_NAMESPACE_OPEN #undef PROTOBUF_NAMESPACE_CLOSE diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index a32f2d8657db..3e3f601d7eb5 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -654,6 +654,14 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { int Capacity() const; + template + static inline typename TypeHandler::Type* copy( + typename TypeHandler::Type* value) { + auto* new_value = TypeHandler::NewFromPrototype(value, nullptr); + TypeHandler::Merge(*value, new_value); + return new_value; + } + // Used for constructing iterators. void* const* raw_data() const; void** raw_mutable_data() const; @@ -2047,14 +2055,15 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLastInternal( typename TypeHandler::Type* result = UnsafeArenaReleaseLast(); // Now perform a copy if we're on an arena. Arena* arena = GetArena(); - if (arena == NULL) { - return result; - } else { - typename TypeHandler::Type* new_result = - TypeHandler::NewFromPrototype(result, NULL); - TypeHandler::Merge(*result, new_result); - return new_result; - } + + typename TypeHandler::Type* new_result; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + new_result = copy(result); + if (arena == nullptr) delete result; +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + new_result = (arena == nullptr) ? result : copy(result); +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return new_result; } // ReleaseLast() for types that *do not* implement merge/copy behavior -- this @@ -2064,7 +2073,7 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLastInternal( template inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLastInternal( std::false_type) { - GOOGLE_DCHECK(GetArena() == NULL) + GOOGLE_DCHECK(GetArena() == nullptr) << "ReleaseLast() called on a RepeatedPtrField that is on an arena, " << "with a type that does not implement MergeFrom. This is unsafe; " << "please implement MergeFrom for your type."; @@ -2254,7 +2263,7 @@ inline void RepeatedPtrField::DeleteSubrange(int start, int num) { for (int i = 0; i < num; ++i) { RepeatedPtrFieldBase::Delete(start + i); } - ExtractSubrange(start, num, NULL); + UnsafeArenaExtractSubrange(start, num, nullptr); } template @@ -2274,28 +2283,45 @@ inline void RepeatedPtrField::ExtractSubrangeInternal( GOOGLE_DCHECK_GE(num, 0); GOOGLE_DCHECK_LE(start + num, size()); - if (num > 0) { - // Save the values of the removed elements if requested. - if (elements != NULL) { - if (GetArena() != NULL) { - // If we're on an arena, we perform a copy for each element so that the - // returned elements are heap-allocated. - for (int i = 0; i < num; ++i) { - Element* element = - RepeatedPtrFieldBase::Mutable(i + start); - typename TypeHandler::Type* new_value = - TypeHandler::NewFromPrototype(element, NULL); - TypeHandler::Merge(*element, new_value); - elements[i] = new_value; - } - } else { - for (int i = 0; i < num; ++i) { - elements[i] = RepeatedPtrFieldBase::Mutable(i + start); - } - } - } + if (num == 0) return; + +#ifdef PROTOBUF_MUST_USE_EXTRACT_RESULT + GOOGLE_DCHECK_NE(elements, nullptr) + << "Releasing elements without transferring ownership is an unsafe " + "operation. Use UnsafeArenaExtractSubrange."; +#endif + if (elements == nullptr) { CloseGap(start, num); + return; + } + + Arena* arena = GetArena(); +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + // Always copy. + for (int i = 0; i < num; ++i) { + elements[i] = copy( + RepeatedPtrFieldBase::Mutable(i + start)); + } + if (arena == nullptr) { + for (int i = 0; i < num; ++i) { + delete RepeatedPtrFieldBase::Mutable(i + start); + } + } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + // If we're on an arena, we perform a copy for each element so that the + // returned elements are heap-allocated. Otherwise, just forward it. + if (arena != nullptr) { + for (int i = 0; i < num; ++i) { + elements[i] = copy( + RepeatedPtrFieldBase::Mutable(i + start)); + } + } else { + for (int i = 0; i < num; ++i) { + elements[i] = RepeatedPtrFieldBase::Mutable(i + start); + } } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + CloseGap(start, num); } // ExtractSubrange() implementation for types that do not implement merge/copy diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index 7363c3d6f9d3..3425dd48bd7c 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -180,7 +180,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* SourceContext::_InternalSerialize( (void) cached_has_bits; // string file_name = 1; - if (!this->file_name().empty()) { + if (!this->_internal_file_name().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_file_name().data(), static_cast(this->_internal_file_name().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -206,7 +206,7 @@ size_t SourceContext::ByteSizeLong() const { (void) cached_has_bits; // string file_name = 1; - if (!this->file_name().empty()) { + if (!this->_internal_file_name().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_file_name()); @@ -240,7 +240,7 @@ void SourceContext::MergeFrom(const SourceContext& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (!from.file_name().empty()) { + if (!from._internal_file_name().empty()) { _internal_set_file_name(from._internal_file_name()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); diff --git a/src/google/protobuf/stubs/substitute.cc b/src/google/protobuf/stubs/substitute.cc index 92107416eb1b..d301682ee337 100644 --- a/src/google/protobuf/stubs/substitute.cc +++ b/src/google/protobuf/stubs/substitute.cc @@ -52,15 +52,15 @@ static int CountSubstituteArgs(const SubstituteArg* const* args_array) { return count; } -std::string Substitute(const char* format, const SubstituteArg& arg0, +std::string Substitute(const std::string& format, const SubstituteArg& arg0, const SubstituteArg& arg1, const SubstituteArg& arg2, const SubstituteArg& arg3, const SubstituteArg& arg4, const SubstituteArg& arg5, const SubstituteArg& arg6, const SubstituteArg& arg7, const SubstituteArg& arg8, const SubstituteArg& arg9) { std::string result; - SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4, - arg5, arg6, arg7, arg8, arg9); + SubstituteAndAppend(&result, format.c_str(), arg0, arg1, arg2, arg3, arg4, + arg5, arg6, arg7, arg8, arg9); return result; } diff --git a/src/google/protobuf/stubs/substitute.h b/src/google/protobuf/stubs/substitute.h index d4e72e1c5166..0f851de096ed 100644 --- a/src/google/protobuf/stubs/substitute.h +++ b/src/google/protobuf/stubs/substitute.h @@ -31,10 +31,12 @@ // Author: kenton@google.com (Kenton Varda) // from google3/strings/substitute.h -#include #include +#include #include +#include + #ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ #define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ @@ -92,6 +94,8 @@ class SubstituteArg { : text_(value), size_(strlen(text_)) {} inline SubstituteArg(const std::string& value) : text_(value.data()), size_(value.size()) {} + inline SubstituteArg(const StringPiece value) + : text_(value.data()), size_(value.size()) {} // Indicates that no argument was given. inline explicit SubstituteArg() @@ -140,7 +144,7 @@ class SubstituteArg { } // namespace internal PROTOBUF_EXPORT std::string Substitute( - const char* format, + const std::string& format, const internal::SubstituteArg& arg0 = internal::SubstituteArg(), const internal::SubstituteArg& arg1 = internal::SubstituteArg(), const internal::SubstituteArg& arg2 = internal::SubstituteArg(), diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index 8441f4714405..f87380c29260 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc @@ -189,13 +189,13 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Timestamp::_InternalSerialize( (void) cached_has_bits; // int64 seconds = 1; - if (this->seconds() != 0) { + if (this->_internal_seconds() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(1, this->_internal_seconds(), target); } // int32 nanos = 2; - if (this->nanos() != 0) { + if (this->_internal_nanos() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_nanos(), target); } @@ -217,14 +217,14 @@ size_t Timestamp::ByteSizeLong() const { (void) cached_has_bits; // int64 seconds = 1; - if (this->seconds() != 0) { + if (this->_internal_seconds() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( this->_internal_seconds()); } // int32 nanos = 2; - if (this->nanos() != 0) { + if (this->_internal_nanos() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( this->_internal_nanos()); @@ -258,10 +258,10 @@ void Timestamp::MergeFrom(const Timestamp& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (from.seconds() != 0) { + if (from._internal_seconds() != 0) { _internal_set_seconds(from._internal_seconds()); } - if (from.nanos() != 0) { + if (from._internal_nanos() != 0) { _internal_set_nanos(from._internal_nanos()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index 04b2b5f6d98b..06d8d7db485b 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -527,7 +527,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Type::_InternalSerialize( (void) cached_has_bits; // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_name().data(), static_cast(this->_internal_name().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -563,7 +563,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Type::_InternalSerialize( } // .google.protobuf.SourceContext source_context = 5; - if (this->has_source_context()) { + if (this->_internal_has_source_context()) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: InternalWriteMessage( @@ -571,7 +571,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Type::_InternalSerialize( } // .google.protobuf.Syntax syntax = 6; - if (this->syntax() != 0) { + if (this->_internal_syntax() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( 6, this->_internal_syntax(), target); @@ -616,21 +616,21 @@ size_t Type::ByteSizeLong() const { } // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_name()); } // .google.protobuf.SourceContext source_context = 5; - if (this->has_source_context()) { + if (this->_internal_has_source_context()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( *source_context_); } // .google.protobuf.Syntax syntax = 6; - if (this->syntax() != 0) { + if (this->_internal_syntax() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); } @@ -666,13 +666,13 @@ void Type::MergeFrom(const Type& from) { fields_.MergeFrom(from.fields_); oneofs_.MergeFrom(from.oneofs_); options_.MergeFrom(from.options_); - if (!from.name().empty()) { + if (!from._internal_name().empty()) { _internal_set_name(from._internal_name()); } - if (from.has_source_context()) { + if (from._internal_has_source_context()) { _internal_mutable_source_context()->PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(from._internal_source_context()); } - if (from.syntax() != 0) { + if (from._internal_syntax() != 0) { _internal_set_syntax(from._internal_syntax()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -934,27 +934,27 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Field::_InternalSerialize( (void) cached_has_bits; // .google.protobuf.Field.Kind kind = 1; - if (this->kind() != 0) { + if (this->_internal_kind() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( 1, this->_internal_kind(), target); } // .google.protobuf.Field.Cardinality cardinality = 2; - if (this->cardinality() != 0) { + if (this->_internal_cardinality() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( 2, this->_internal_cardinality(), target); } // int32 number = 3; - if (this->number() != 0) { + if (this->_internal_number() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->_internal_number(), target); } // string name = 4; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_name().data(), static_cast(this->_internal_name().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -964,7 +964,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Field::_InternalSerialize( } // string type_url = 6; - if (!this->type_url().empty()) { + if (!this->_internal_type_url().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_type_url().data(), static_cast(this->_internal_type_url().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -974,13 +974,13 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Field::_InternalSerialize( } // int32 oneof_index = 7; - if (this->oneof_index() != 0) { + if (this->_internal_oneof_index() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(7, this->_internal_oneof_index(), target); } // bool packed = 8; - if (this->packed() != 0) { + if (this->_internal_packed() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(8, this->_internal_packed(), target); } @@ -994,7 +994,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Field::_InternalSerialize( } // string json_name = 10; - if (!this->json_name().empty()) { + if (!this->_internal_json_name().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_json_name().data(), static_cast(this->_internal_json_name().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -1004,7 +1004,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Field::_InternalSerialize( } // string default_value = 11; - if (!this->default_value().empty()) { + if (!this->_internal_default_value().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_default_value().data(), static_cast(this->_internal_default_value().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -1037,61 +1037,61 @@ size_t Field::ByteSizeLong() const { } // string name = 4; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_name()); } // string type_url = 6; - if (!this->type_url().empty()) { + if (!this->_internal_type_url().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_type_url()); } // string json_name = 10; - if (!this->json_name().empty()) { + if (!this->_internal_json_name().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_json_name()); } // string default_value = 11; - if (!this->default_value().empty()) { + if (!this->_internal_default_value().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_default_value()); } // .google.protobuf.Field.Kind kind = 1; - if (this->kind() != 0) { + if (this->_internal_kind() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_kind()); } // .google.protobuf.Field.Cardinality cardinality = 2; - if (this->cardinality() != 0) { + if (this->_internal_cardinality() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_cardinality()); } // int32 number = 3; - if (this->number() != 0) { + if (this->_internal_number() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( this->_internal_number()); } // int32 oneof_index = 7; - if (this->oneof_index() != 0) { + if (this->_internal_oneof_index() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( this->_internal_oneof_index()); } // bool packed = 8; - if (this->packed() != 0) { + if (this->_internal_packed() != 0) { total_size += 1 + 1; } @@ -1124,31 +1124,31 @@ void Field::MergeFrom(const Field& from) { (void) cached_has_bits; options_.MergeFrom(from.options_); - if (!from.name().empty()) { + if (!from._internal_name().empty()) { _internal_set_name(from._internal_name()); } - if (!from.type_url().empty()) { + if (!from._internal_type_url().empty()) { _internal_set_type_url(from._internal_type_url()); } - if (!from.json_name().empty()) { + if (!from._internal_json_name().empty()) { _internal_set_json_name(from._internal_json_name()); } - if (!from.default_value().empty()) { + if (!from._internal_default_value().empty()) { _internal_set_default_value(from._internal_default_value()); } - if (from.kind() != 0) { + if (from._internal_kind() != 0) { _internal_set_kind(from._internal_kind()); } - if (from.cardinality() != 0) { + if (from._internal_cardinality() != 0) { _internal_set_cardinality(from._internal_cardinality()); } - if (from.number() != 0) { + if (from._internal_number() != 0) { _internal_set_number(from._internal_number()); } - if (from.oneof_index() != 0) { + if (from._internal_oneof_index() != 0) { _internal_set_oneof_index(from._internal_oneof_index()); } - if (from.packed() != 0) { + if (from._internal_packed() != 0) { _internal_set_packed(from._internal_packed()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -1382,7 +1382,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Enum::_InternalSerialize( (void) cached_has_bits; // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_name().data(), static_cast(this->_internal_name().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -1408,7 +1408,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Enum::_InternalSerialize( } // .google.protobuf.SourceContext source_context = 4; - if (this->has_source_context()) { + if (this->_internal_has_source_context()) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: InternalWriteMessage( @@ -1416,7 +1416,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Enum::_InternalSerialize( } // .google.protobuf.Syntax syntax = 5; - if (this->syntax() != 0) { + if (this->_internal_syntax() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( 5, this->_internal_syntax(), target); @@ -1453,21 +1453,21 @@ size_t Enum::ByteSizeLong() const { } // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_name()); } // .google.protobuf.SourceContext source_context = 4; - if (this->has_source_context()) { + if (this->_internal_has_source_context()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( *source_context_); } // .google.protobuf.Syntax syntax = 5; - if (this->syntax() != 0) { + if (this->_internal_syntax() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_syntax()); } @@ -1502,13 +1502,13 @@ void Enum::MergeFrom(const Enum& from) { enumvalue_.MergeFrom(from.enumvalue_); options_.MergeFrom(from.options_); - if (!from.name().empty()) { + if (!from._internal_name().empty()) { _internal_set_name(from._internal_name()); } - if (from.has_source_context()) { + if (from._internal_has_source_context()) { _internal_mutable_source_context()->PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(from._internal_source_context()); } - if (from.syntax() != 0) { + if (from._internal_syntax() != 0) { _internal_set_syntax(from._internal_syntax()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -1681,7 +1681,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* EnumValue::_InternalSerialize( (void) cached_has_bits; // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_name().data(), static_cast(this->_internal_name().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -1691,7 +1691,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* EnumValue::_InternalSerialize( } // int32 number = 2; - if (this->number() != 0) { + if (this->_internal_number() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_number(), target); } @@ -1728,14 +1728,14 @@ size_t EnumValue::ByteSizeLong() const { } // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_name()); } // int32 number = 2; - if (this->number() != 0) { + if (this->_internal_number() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( this->_internal_number()); @@ -1770,10 +1770,10 @@ void EnumValue::MergeFrom(const EnumValue& from) { (void) cached_has_bits; options_.MergeFrom(from.options_); - if (!from.name().empty()) { + if (!from._internal_name().empty()) { _internal_set_name(from._internal_name()); } - if (from.number() != 0) { + if (from._internal_number() != 0) { _internal_set_number(from._internal_number()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -1944,7 +1944,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Option::_InternalSerialize( (void) cached_has_bits; // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_name().data(), static_cast(this->_internal_name().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -1954,7 +1954,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Option::_InternalSerialize( } // .google.protobuf.Any value = 2; - if (this->has_value()) { + if (this->_internal_has_value()) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: InternalWriteMessage( @@ -1978,14 +1978,14 @@ size_t Option::ByteSizeLong() const { (void) cached_has_bits; // string name = 1; - if (!this->name().empty()) { + if (!this->_internal_name().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_name()); } // .google.protobuf.Any value = 2; - if (this->has_value()) { + if (this->_internal_has_value()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( *value_); @@ -2019,10 +2019,10 @@ void Option::MergeFrom(const Option& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (!from.name().empty()) { + if (!from._internal_name().empty()) { _internal_set_name(from._internal_name()); } - if (from.has_value()) { + if (from._internal_has_value()) { _internal_mutable_value()->PROTOBUF_NAMESPACE_ID::Any::MergeFrom(from._internal_value()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index 19fc8d773722..2ab894c6b9ff 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h @@ -1581,9 +1581,15 @@ inline PROTOBUF_NAMESPACE_ID::SourceContext* Type::release_source_context() { PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; source_context_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::SourceContext* Type::unsafe_arena_release_source_context() { @@ -2139,9 +2145,15 @@ inline PROTOBUF_NAMESPACE_ID::SourceContext* Enum::release_source_context() { PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; source_context_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::SourceContext* Enum::unsafe_arena_release_source_context() { @@ -2399,9 +2411,15 @@ inline PROTOBUF_NAMESPACE_ID::Any* Option::release_value() { PROTOBUF_NAMESPACE_ID::Any* temp = value_; value_ = nullptr; +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* old = reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp); + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + if (GetArenaForAllocation() == nullptr) { delete old; } +#else // PROTOBUF_FORCE_COPY_IN_RELEASE if (GetArenaForAllocation() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE return temp; } inline PROTOBUF_NAMESPACE_ID::Any* Option::unsafe_arena_release_value() { diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc index 2732140153fd..998758121d64 100644 --- a/src/google/protobuf/wrappers.pb.cc +++ b/src/google/protobuf/wrappers.pb.cc @@ -339,7 +339,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* DoubleValue::_InternalSerialize( (void) cached_has_bits; // double value = 1; - if (!(this->value() <= 0 && this->value() >= 0)) { + if (!(this->_internal_value() <= 0 && this->_internal_value() >= 0)) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteDoubleToArray(1, this->_internal_value(), target); } @@ -361,7 +361,7 @@ size_t DoubleValue::ByteSizeLong() const { (void) cached_has_bits; // double value = 1; - if (!(this->value() <= 0 && this->value() >= 0)) { + if (!(this->_internal_value() <= 0 && this->_internal_value() >= 0)) { total_size += 1 + 8; } @@ -393,7 +393,7 @@ void DoubleValue::MergeFrom(const DoubleValue& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (!(from.value() <= 0 && from.value() >= 0)) { + if (!(from._internal_value() <= 0 && from._internal_value() >= 0)) { _internal_set_value(from._internal_value()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -522,7 +522,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* FloatValue::_InternalSerialize( (void) cached_has_bits; // float value = 1; - if (!(this->value() <= 0 && this->value() >= 0)) { + if (!(this->_internal_value() <= 0 && this->_internal_value() >= 0)) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteFloatToArray(1, this->_internal_value(), target); } @@ -544,7 +544,7 @@ size_t FloatValue::ByteSizeLong() const { (void) cached_has_bits; // float value = 1; - if (!(this->value() <= 0 && this->value() >= 0)) { + if (!(this->_internal_value() <= 0 && this->_internal_value() >= 0)) { total_size += 1 + 4; } @@ -576,7 +576,7 @@ void FloatValue::MergeFrom(const FloatValue& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (!(from.value() <= 0 && from.value() >= 0)) { + if (!(from._internal_value() <= 0 && from._internal_value() >= 0)) { _internal_set_value(from._internal_value()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -705,7 +705,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Int64Value::_InternalSerialize( (void) cached_has_bits; // int64 value = 1; - if (this->value() != 0) { + if (this->_internal_value() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(1, this->_internal_value(), target); } @@ -727,7 +727,7 @@ size_t Int64Value::ByteSizeLong() const { (void) cached_has_bits; // int64 value = 1; - if (this->value() != 0) { + if (this->_internal_value() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64Size( this->_internal_value()); @@ -761,7 +761,7 @@ void Int64Value::MergeFrom(const Int64Value& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (from.value() != 0) { + if (from._internal_value() != 0) { _internal_set_value(from._internal_value()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -890,7 +890,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* UInt64Value::_InternalSerialize( (void) cached_has_bits; // uint64 value = 1; - if (this->value() != 0) { + if (this->_internal_value() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt64ToArray(1, this->_internal_value(), target); } @@ -912,7 +912,7 @@ size_t UInt64Value::ByteSizeLong() const { (void) cached_has_bits; // uint64 value = 1; - if (this->value() != 0) { + if (this->_internal_value() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64Size( this->_internal_value()); @@ -946,7 +946,7 @@ void UInt64Value::MergeFrom(const UInt64Value& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (from.value() != 0) { + if (from._internal_value() != 0) { _internal_set_value(from._internal_value()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -1075,7 +1075,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Int32Value::_InternalSerialize( (void) cached_has_bits; // int32 value = 1; - if (this->value() != 0) { + if (this->_internal_value() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_value(), target); } @@ -1097,7 +1097,7 @@ size_t Int32Value::ByteSizeLong() const { (void) cached_has_bits; // int32 value = 1; - if (this->value() != 0) { + if (this->_internal_value() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( this->_internal_value()); @@ -1131,7 +1131,7 @@ void Int32Value::MergeFrom(const Int32Value& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (from.value() != 0) { + if (from._internal_value() != 0) { _internal_set_value(from._internal_value()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -1260,7 +1260,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* UInt32Value::_InternalSerialize( (void) cached_has_bits; // uint32 value = 1; - if (this->value() != 0) { + if (this->_internal_value() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt32ToArray(1, this->_internal_value(), target); } @@ -1282,7 +1282,7 @@ size_t UInt32Value::ByteSizeLong() const { (void) cached_has_bits; // uint32 value = 1; - if (this->value() != 0) { + if (this->_internal_value() != 0) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt32Size( this->_internal_value()); @@ -1316,7 +1316,7 @@ void UInt32Value::MergeFrom(const UInt32Value& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (from.value() != 0) { + if (from._internal_value() != 0) { _internal_set_value(from._internal_value()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -1445,7 +1445,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* BoolValue::_InternalSerialize( (void) cached_has_bits; // bool value = 1; - if (this->value() != 0) { + if (this->_internal_value() != 0) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(1, this->_internal_value(), target); } @@ -1467,7 +1467,7 @@ size_t BoolValue::ByteSizeLong() const { (void) cached_has_bits; // bool value = 1; - if (this->value() != 0) { + if (this->_internal_value() != 0) { total_size += 1 + 1; } @@ -1499,7 +1499,7 @@ void BoolValue::MergeFrom(const BoolValue& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (from.value() != 0) { + if (from._internal_value() != 0) { _internal_set_value(from._internal_value()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -1635,7 +1635,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* StringValue::_InternalSerialize( (void) cached_has_bits; // string value = 1; - if (!this->value().empty()) { + if (!this->_internal_value().empty()) { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String( this->_internal_value().data(), static_cast(this->_internal_value().length()), ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE, @@ -1661,7 +1661,7 @@ size_t StringValue::ByteSizeLong() const { (void) cached_has_bits; // string value = 1; - if (!this->value().empty()) { + if (!this->_internal_value().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( this->_internal_value()); @@ -1695,7 +1695,7 @@ void StringValue::MergeFrom(const StringValue& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (!from.value().empty()) { + if (!from._internal_value().empty()) { _internal_set_value(from._internal_value()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); @@ -1834,7 +1834,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* BytesValue::_InternalSerialize( (void) cached_has_bits; // bytes value = 1; - if (!this->value().empty()) { + if (!this->_internal_value().empty()) { target = stream->WriteBytesMaybeAliased( 1, this->_internal_value(), target); } @@ -1856,7 +1856,7 @@ size_t BytesValue::ByteSizeLong() const { (void) cached_has_bits; // bytes value = 1; - if (!this->value().empty()) { + if (!this->_internal_value().empty()) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( this->_internal_value()); @@ -1890,7 +1890,7 @@ void BytesValue::MergeFrom(const BytesValue& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; - if (!from.value().empty()) { + if (!from._internal_value().empty()) { _internal_set_value(from._internal_value()); } _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);