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
pull/15809/head
Protobuf Team Bot 10 months ago committed by Copybara-Service
parent 4d3931d626
commit d49dacca20
  1. 11
      src/google/protobuf/compiler/cpp/message.cc
  2. 35
      src/google/protobuf/generated_message_tctable_decl.h
  3. 2
      src/google/protobuf/generated_message_tctable_lite.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");
}

@ -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 <typename T, const char* (*func)(T*, const char*, ParseContext*)>
const char* StubParseImpl(PROTOBUF_TC_PARAM_DECL) {
return func(static_cast<T*>(msg), ptr, ctx);
}
template <typename T, const char* (*func)(T*, const char*, ParseContext*)>
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<T, func>, {}}}},
};
}
} // namespace internal
} // namespace protobuf
} // namespace google

@ -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;
}

Loading…
Cancel
Save