From d49dacca206c424c80140eb9614688ad654c519d Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 13 Feb 2024 12:44:09 -0800 Subject: [PATCH] Add helper function to generate stub TcParse tables with only a single handler. Useful for test non-codegen types that have their own parsing logic. Also forward the `ptr` through the post_loop_handler to allow it to fail. PiperOrigin-RevId: 606714285 --- src/google/protobuf/compiler/cpp/message.cc | 11 +++--- .../protobuf/generated_message_tctable_decl.h | 35 ++++++++++++++++++- .../generated_message_tctable_lite.cc | 2 +- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 996d3beeea..5ecf41af78 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -1947,8 +1947,9 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { [&] { if (!NeedsPostLoopHandler(descriptor_, options_)) return; p->Emit(R"cc( - static void PostLoopHandler(MessageLite* msg, - $pbi$::ParseContext* ctx); + static const char* PostLoopHandler(MessageLite* msg, + const char* ptr, + $pbi$::ParseContext* ctx); )cc"); }}, {"decl_impl", [&] { GenerateImplDefinition(p); }}, @@ -2301,11 +2302,13 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) { [&] { }}}, R"cc( - void $classname$::PostLoopHandler(MessageLite* msg, - ::_pbi::ParseContext* ctx) { + const char* $classname$::PostLoopHandler(MessageLite* msg, + const char* ptr, + ::_pbi::ParseContext* ctx) { $classname$* _this = static_cast<$classname$*>(msg); $annotate_deserialize$; $required$; + return ptr; } )cc"); } diff --git a/src/google/protobuf/generated_message_tctable_decl.h b/src/google/protobuf/generated_message_tctable_decl.h index 4bff7ca52d..7cea41f960 100644 --- a/src/google/protobuf/generated_message_tctable_decl.h +++ b/src/google/protobuf/generated_message_tctable_decl.h @@ -285,7 +285,8 @@ struct alignas(uint64_t) TcParseTableBase { uint32_t aux_offset; const MessageLite* default_instance; - using PostLoopHandler = void (*)(MessageLite* msg, ParseContext* ctx); + using PostLoopHandler = const char* (*)(MessageLite* msg, const char* ptr, + ParseContext* ctx); PostLoopHandler post_loop_handler; // Handler for fields which are not handled by table dispatch. @@ -541,6 +542,38 @@ static_assert(offsetof(TcParseTable<1>, fast_entries) == sizeof(TcParseTableBase), "Table entries must be laid out after TcParseTableBase."); +template +const char* StubParseImpl(PROTOBUF_TC_PARAM_DECL) { + return func(static_cast(msg), ptr, ctx); +} + +template +constexpr TcParseTable<0> CreateStubTcParseTable( + const MessageLite* default_instance, + TcParseTableBase::PostLoopHandler post_loop_handler = nullptr) { + return { + { + 0, // has_bits_offset + 0, // extension_offset + 0, // max_field_number + 0, // fast_idx_mask + 0, // lookup_table_offset + 0, // skipmap32 + 0, // field_entries_offset + 0, // num_field_entries + 0, // num_aux_entries + 0, // aux_offset + default_instance, // + post_loop_handler, // + nullptr, // fallback +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + nullptr, // to_prefetch +#endif // PROTOBUF_PREFETCH_PARSE_TABLE + }, + {{{StubParseImpl, {}}}}, + }; +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/generated_message_tctable_lite.cc b/src/google/protobuf/generated_message_tctable_lite.cc index 90cb70b6fe..53aabd01b8 100644 --- a/src/google/protobuf/generated_message_tctable_lite.cc +++ b/src/google/protobuf/generated_message_tctable_lite.cc @@ -97,7 +97,7 @@ inline PROTOBUF_ALWAYS_INLINE const char* TcParser::ParseLoopInlined( } table -= 1; if (ABSL_PREDICT_FALSE(table->has_post_loop_handler)) { - table->post_loop_handler(msg, ctx); + return table->post_loop_handler(msg, ptr, ctx); } return ptr; }