From ed400ea5177a3ed10e6749ceb99077649828008a Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Mon, 12 Feb 2024 14:23:34 -0800 Subject: [PATCH] Add a TcParseTable pointer in `ClassData` and change the default `_InternalParse` implementation to use it. For LITE messages, populate the entry in `ClassData` and remove the override for `_InternalParse`. PiperOrigin-RevId: 606364791 --- src/google/protobuf/compiler/cpp/message.cc | 1 + .../compiler/cpp/parse_function_generator.cc | 8 +++++++ src/google/protobuf/message_lite.cc | 12 ++++++++++ src/google/protobuf/message_lite.h | 22 ++++++++++++++----- 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 7506f897df..996d3beeea 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -3649,6 +3649,7 @@ void MessageGenerator::GenerateClassData(io::Printer* p) { PROTOBUF_CONSTINIT static const ClassDataLite<$type_size$> _data_ = { { + &_table_.header, $on_demand_register_arena_dtor$, PROTOBUF_FIELD_OFFSET($classname$, $cached_size$), true, diff --git a/src/google/protobuf/compiler/cpp/parse_function_generator.cc b/src/google/protobuf/compiler/cpp/parse_function_generator.cc index 1025e35efe..c14388716d 100644 --- a/src/google/protobuf/compiler/cpp/parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/parse_function_generator.cc @@ -116,7 +116,14 @@ ParseFunctionGenerator::ParseFunctionGenerator( variables_["classname"] = ClassName(descriptor, false); } +static bool ShouldGenerateInternalParse(const Descriptor* descriptor, + const Options& options) { + return HasGeneratedMethods(descriptor->file(), options) && + HasDescriptorMethods(descriptor->file(), options); +} + void ParseFunctionGenerator::GenerateMethodDecls(io::Printer* printer) { + if (!ShouldGenerateInternalParse(descriptor_, options_)) return; Formatter format(printer, variables_); format( "const char* _InternalParse(const char* ptr, " @@ -124,6 +131,7 @@ void ParseFunctionGenerator::GenerateMethodDecls(io::Printer* printer) { } void ParseFunctionGenerator::GenerateMethodImpls(io::Printer* printer) { + if (!ShouldGenerateInternalParse(descriptor_, options_)) return; printer->Emit(R"cc( const char* $classname$::_InternalParse(const char* ptr, ::_pbi::ParseContext* ctx) { diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 468ffc584d..0bea072a2e 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -31,6 +31,7 @@ #include "absl/synchronization/mutex.h" #include "absl/types/optional.h" #include "google/protobuf/arena.h" +#include "google/protobuf/generated_message_tctable_impl.h" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/zero_copy_stream.h" #include "google/protobuf/io/zero_copy_stream_impl.h" @@ -44,6 +45,17 @@ namespace google { namespace protobuf { +const char* MessageLite::_InternalParse(const char* ptr, + internal::ParseContext* ctx) { + auto* data = GetClassData(); + ABSL_DCHECK(data != nullptr); + + if (data->tc_table != nullptr) { + return internal::TcParser::ParseLoop(this, ptr, ctx, data->tc_table); + } + return nullptr; +} + std::string MessageLite::GetTypeName() const { auto* data = GetClassData(); ABSL_DCHECK(data != nullptr); diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index 17bf95eea1..b3ff143256 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -130,6 +130,7 @@ class ExtensionSet; class LazyField; class RepeatedPtrFieldBase; class TcParser; +struct TcParseTableBase; class WireFormatLite; class WeakFieldMap; @@ -494,10 +495,8 @@ class PROTOBUF_EXPORT MessageLite { // method.) int GetCachedSize() const; - virtual const char* _InternalParse(const char* /*ptr*/, - internal::ParseContext* /*ctx*/) { - return nullptr; - } + virtual const char* _InternalParse(const char* ptr, + internal::ParseContext* ctx); void OnDemandRegisterArenaDtor(Arena* arena); @@ -536,6 +535,7 @@ class PROTOBUF_EXPORT MessageLite { // otherwise be null. We can have some metadata in ClassData telling us if we // have them and their offset. struct ClassData { + const internal::TcParseTableBase* tc_table; void (*on_demand_register_arena_dtor)(MessageLite& msg, Arena& arena); // Offset of the CachedSize member. @@ -544,10 +544,22 @@ class PROTOBUF_EXPORT MessageLite { // char[] just beyond the ClassData. bool is_lite; + // Temporary constructor while we migrate existing classes to populate the + // `tc_table` field. constexpr ClassData(void (*on_demand_register_arena_dtor)(MessageLite&, Arena&), uint32_t cached_size_offset, bool is_lite) - : on_demand_register_arena_dtor(on_demand_register_arena_dtor), + : tc_table(), + on_demand_register_arena_dtor(on_demand_register_arena_dtor), + cached_size_offset(cached_size_offset), + is_lite(is_lite) {} + + constexpr ClassData(const internal::TcParseTableBase* tc_table, + void (*on_demand_register_arena_dtor)(MessageLite&, + Arena&), + uint32_t cached_size_offset, bool is_lite) + : tc_table(tc_table), + on_demand_register_arena_dtor(on_demand_register_arena_dtor), cached_size_offset(cached_size_offset), is_lite(is_lite) {}