diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 463f31a37f..650cd46f50 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -3551,6 +3551,19 @@ void MessageGenerator::GenerateClassData(io::Printer* p) { { {"on_demand_register_arena_dtor", on_demand_register_arena_dtor}, {"pin_weak_descriptor", pin_weak_descriptor}, + {"table", + [&] { + // Map entries use the dynamic parser. + if (IsMapEntryMessage(descriptor_)) { + p->Emit(R"cc( + nullptr, // tc_table + )cc"); + } else { + p->Emit(R"cc( + &_table_.header, + )cc"); + } + }}, {"tracker_on_get_metadata", [&] { if (HasTracker(descriptor_, options_)) { @@ -3571,6 +3584,7 @@ void MessageGenerator::GenerateClassData(io::Printer* p) { PROTOBUF_CONSTINIT static const ::$proto_ns$::MessageLite:: ClassDataFull _data_ = { { + $table$, $on_demand_register_arena_dtor$, PROTOBUF_FIELD_OFFSET($classname$, $cached_size$), false, diff --git a/src/google/protobuf/compiler/java/java_features.pb.cc b/src/google/protobuf/compiler/java/java_features.pb.cc index 4352648ea3..78d404c90c 100644 --- a/src/google/protobuf/compiler/java/java_features.pb.cc +++ b/src/google/protobuf/compiler/java/java_features.pb.cc @@ -177,6 +177,7 @@ JavaFeatures::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(JavaFeatures, _impl_._cached_size_), false, diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index 86f6e3188d..aef3971530 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -363,6 +363,7 @@ Version::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(Version, _impl_._cached_size_), false, @@ -674,6 +675,7 @@ CodeGeneratorRequest::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_._cached_size_), false, @@ -1021,6 +1023,7 @@ CodeGeneratorResponse_File::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_._cached_size_), false, @@ -1341,6 +1344,7 @@ CodeGeneratorResponse::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_._cached_size_), false, diff --git a/src/google/protobuf/cpp_features.pb.cc b/src/google/protobuf/cpp_features.pb.cc index 57a6f3945e..a5822da2aa 100644 --- a/src/google/protobuf/cpp_features.pb.cc +++ b/src/google/protobuf/cpp_features.pb.cc @@ -177,6 +177,7 @@ CppFeatures::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_._cached_size_), false, diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index ee06e96068..4573d67089 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -2384,6 +2384,7 @@ FileDescriptorSet::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(FileDescriptorSet, _impl_._cached_size_), false, @@ -2617,6 +2618,7 @@ FileDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_._cached_size_), false, @@ -3191,6 +3193,7 @@ DescriptorProto_ExtensionRange::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_._cached_size_), false, @@ -3453,6 +3456,7 @@ DescriptorProto_ReservedRange::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_._cached_size_), false, @@ -3711,6 +3715,7 @@ DescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_._cached_size_), false, @@ -4203,6 +4208,7 @@ ExtensionRangeOptions_Declaration::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions_Declaration, _impl_._cached_size_), false, @@ -4536,6 +4542,7 @@ ExtensionRangeOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_._cached_size_), false, @@ -4887,6 +4894,7 @@ FieldDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_._cached_size_), false, @@ -5389,6 +5397,7 @@ OneofDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(OneofDescriptorProto, _impl_._cached_size_), false, @@ -5630,6 +5639,7 @@ EnumDescriptorProto_EnumReservedRange::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_._cached_size_), false, @@ -5878,6 +5888,7 @@ EnumDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_._cached_size_), false, @@ -6223,6 +6234,7 @@ EnumValueDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_._cached_size_), false, @@ -6511,6 +6523,7 @@ ServiceDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_._cached_size_), false, @@ -6815,6 +6828,7 @@ MethodDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_._cached_size_), false, @@ -7226,6 +7240,7 @@ FileOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(FileOptions, _impl_._cached_size_), false, @@ -8012,6 +8027,7 @@ MessageOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_._cached_size_), false, @@ -8384,6 +8400,7 @@ FieldOptions_EditionDefault::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(FieldOptions_EditionDefault, _impl_._cached_size_), false, @@ -8645,6 +8662,7 @@ FieldOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_._cached_size_), false, @@ -9179,6 +9197,7 @@ OneofOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_._cached_size_), false, @@ -9455,6 +9474,7 @@ EnumOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_._cached_size_), false, @@ -9805,6 +9825,7 @@ EnumValueOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_._cached_size_), false, @@ -10131,6 +10152,7 @@ ServiceOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_._cached_size_), false, @@ -10438,6 +10460,7 @@ MethodOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_._cached_size_), false, @@ -10760,6 +10783,7 @@ UninterpretedOption_NamePart::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(UninterpretedOption_NamePart, _impl_._cached_size_), false, @@ -11020,6 +11044,7 @@ UninterpretedOption::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_._cached_size_), false, @@ -11405,6 +11430,7 @@ FeatureSet::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_._cached_size_), false, @@ -11756,6 +11782,7 @@ FeatureSetDefaults_FeatureSetEditionDefault::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_._cached_size_), false, @@ -12014,6 +12041,7 @@ FeatureSetDefaults::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_._cached_size_), false, @@ -12289,6 +12317,7 @@ SourceCodeInfo_Location::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(SourceCodeInfo_Location, _impl_._cached_size_), false, @@ -12616,6 +12645,7 @@ SourceCodeInfo::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(SourceCodeInfo, _impl_._cached_size_), false, @@ -12829,6 +12859,7 @@ GeneratedCodeInfo_Annotation::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_._cached_size_), false, @@ -13148,6 +13179,7 @@ GeneratedCodeInfo::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite:: ClassDataFull _data_ = { { + &_table_.header, nullptr, // OnDemandRegisterArenaDtor PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo, _impl_._cached_size_), false, diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index 5c20f8190b..d4925174f8 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -154,7 +154,7 @@ void ExtensionSet::RegisterMessageExtension(const MessageLite* extendee, type == WireFormatLite::TYPE_GROUP); ExtensionInfo info(extendee, number, type, is_repeated, is_packed, verify_func, is_lazy); - info.message_info = {prototype}; + info.message_info = {prototype, prototype->GetTcParseTable()}; Register(info); } diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index d1ac7cde02..f2126bb8de 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -139,6 +139,8 @@ struct ExtensionInfo { struct MessageInfo { const MessageLite* prototype; + // The TcParse table used for this object. Never null. + const internal::TcParseTableBase* tc_table; }; union { diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index 3f5bd8ff63..dad4937993 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc @@ -24,6 +24,7 @@ #include "google/protobuf/extension_set.h" #include "google/protobuf/extension_set_inl.h" #include "google/protobuf/generated_message_reflection.h" +#include "google/protobuf/generated_message_tctable_impl.h" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/message.h" #include "google/protobuf/message_lite.h" @@ -272,6 +273,8 @@ bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) { if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { output->message_info.prototype = factory_->GetPrototype(extension->message_type()); + output->message_info.tc_table = + output->message_info.prototype->GetTcParseTable(); ABSL_CHECK(output->message_info.prototype != nullptr) << "Extension factory's GetPrototype() returned nullptr; extension: " << extension->full_name(); diff --git a/src/google/protobuf/generated_message_tctable_impl.h b/src/google/protobuf/generated_message_tctable_impl.h index 260556d7f9..838e748501 100644 --- a/src/google/protobuf/generated_message_tctable_impl.h +++ b/src/google/protobuf/generated_message_tctable_impl.h @@ -14,6 +14,7 @@ #include #include +#include "absl/base/optimization.h" #include "absl/log/absl_log.h" #include "google/protobuf/extension_set.h" #include "google/protobuf/generated_message_tctable_decl.h" @@ -377,6 +378,22 @@ class PROTOBUF_EXPORT TcParser final { return &T::_table_.header; } + static PROTOBUF_ALWAYS_INLINE const char* ParseMessage( + MessageLite* msg, const char* ptr, ParseContext* ctx, + const TcParseTableBase* tc_table) { + return ctx->ParseLengthDelimitedInlined(ptr, [&](const char* ptr) { + return ParseLoopInlined(msg, ptr, ctx, tc_table); + }); + } + + static PROTOBUF_ALWAYS_INLINE const char* ParseGroup( + MessageLite* msg, const char* ptr, ParseContext* ctx, + const TcParseTableBase* tc_table, uint32_t start_tag) { + return ctx->ParseGroupInlined(ptr, start_tag, [&](const char* ptr) { + return ParseLoopInlined(msg, ptr, ctx, tc_table); + }); + } + // == ABI of the tail call functions == // All the tail call functions have the same signature as required by clang's // `musttail` attribute. However, their ABIs are different. @@ -976,6 +993,35 @@ inline PROTOBUF_ALWAYS_INLINE const char* TcParser::ToParseLoop( return ptr; } +inline PROTOBUF_ALWAYS_INLINE const char* TcParser::ParseLoopInlined( + MessageLite* msg, const char* ptr, ParseContext* ctx, + const TcParseTableBase* table) { + // Note: TagDispatch uses a dispatch table at "&table->fast_entries". + // For fast dispatch, we'd like to have a pointer to that, but if we use + // that expression, there's no easy way to get back to "table", which we also + // need during dispatch. It turns out that "table + 1" points exactly to + // fast_entries, so we just increment table by 1 here, to get the register + // holding the value we want. + table += 1; + while (!ctx->Done(&ptr)) { +#if defined(__GNUC__) + // Note: this asm prevents the compiler (clang, specifically) from + // believing (thanks to CSE) that it needs to dedicate a registeer both + // to "table" and "&table->fast_entries". + // TODO: remove this asm + asm("" : "+r"(table)); +#endif + ptr = TagDispatch(msg, ptr, ctx, TcFieldData::DefaultInit(), table - 1, 0); + if (ptr == nullptr) break; + if (ctx->LastTag() != 1) break; // Ended on terminating tag + } + table -= 1; + if (ABSL_PREDICT_FALSE(table->has_post_loop_handler)) { + return table->post_loop_handler(msg, ptr, ctx); + } + return ptr; +} + // Prints the type card as or of labels, using known higher level labels. // Used for code generation, but also useful for debugging. PROTOBUF_EXPORT std::string TypeCardToString(uint16_t type_card); diff --git a/src/google/protobuf/generated_message_tctable_lite.cc b/src/google/protobuf/generated_message_tctable_lite.cc index 9d1ec992fe..f8b0d87942 100644 --- a/src/google/protobuf/generated_message_tctable_lite.cc +++ b/src/google/protobuf/generated_message_tctable_lite.cc @@ -73,35 +73,6 @@ const char* TcParser::GenericFallbackLite(PROTOBUF_TC_PARAM_DECL) { // Core fast parsing implementation: ////////////////////////////////////////////////////////////////////////////// -inline PROTOBUF_ALWAYS_INLINE const char* TcParser::ParseLoopInlined( - MessageLite* msg, const char* ptr, ParseContext* ctx, - const TcParseTableBase* table) { - // Note: TagDispatch uses a dispatch table at "&table->fast_entries". - // For fast dispatch, we'd like to have a pointer to that, but if we use - // that expression, there's no easy way to get back to "table", which we also - // need during dispatch. It turns out that "table + 1" points exactly to - // fast_entries, so we just increment table by 1 here, to get the register - // holding the value we want. - table += 1; - while (!ctx->Done(&ptr)) { -#if defined(__GNUC__) - // Note: this asm prevents the compiler (clang, specifically) from - // believing (thanks to CSE) that it needs to dedicate a registeer both - // to "table" and "&table->fast_entries". - // TODO: remove this asm - asm("" : "+r"(table)); -#endif - ptr = TagDispatch(msg, ptr, ctx, TcFieldData::DefaultInit(), table - 1, 0); - if (ptr == nullptr) break; - if (ctx->LastTag() != 1) break; // Ended on terminating tag - } - table -= 1; - if (ABSL_PREDICT_FALSE(table->has_post_loop_handler)) { - return table->post_loop_handler(msg, ptr, ctx); - } - return ptr; -} - PROTOBUF_NOINLINE const char* TcParser::ParseLoop( MessageLite* msg, const char* ptr, ParseContext* ctx, const TcParseTableBase* table) { diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index f0ab785788..f32e929e8e 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -46,18 +46,22 @@ namespace google { namespace protobuf { -const char* MessageLite::_InternalParse(const char* ptr, - internal::ParseContext* ctx) { +const internal::TcParseTableBase* MessageLite::GetTcParseTable() const { auto* data = GetClassData(); ABSL_DCHECK(data != nullptr); auto* tc_table = data->tc_table; if (ABSL_PREDICT_FALSE(tc_table == nullptr)) { ABSL_DCHECK(!data->is_lite); - tc_table = data->full().descriptor_methods->get_tc_table(*this); + return data->full().descriptor_methods->get_tc_table(*this); } + return tc_table; +} - return internal::TcParser::ParseLoop(this, ptr, ctx, tc_table); +const char* MessageLite::_InternalParse(const char* ptr, + internal::ParseContext* ctx) { + return internal::TcParser::ParseLoopInlined(this, ptr, ctx, + GetTcParseTable()); } std::string MessageLite::GetTypeName() const { diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index e7cdf17330..722bdf990e 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -126,6 +126,7 @@ class SwapFieldHelper; class ParseContext; struct DescriptorTable; +class DescriptorPoolExtensionFinder; class ExtensionSet; class LazyField; class RepeatedPtrFieldBase; @@ -516,6 +517,8 @@ class PROTOBUF_EXPORT MessageLite { return static_cast(Arena::CopyConstruct(arena, &from)); } + const internal::TcParseTableBase* GetTcParseTable() const; + inline explicit MessageLite(Arena* arena) : _internal_metadata_(arena) {} // We use a secondary vtable for descriptor based methods. This way ClassData @@ -660,6 +663,7 @@ class PROTOBUF_EXPORT MessageLite { friend class FastReflectionStringSetter; friend class Message; friend class Reflection; + friend class internal::DescriptorPoolExtensionFinder; friend class internal::ExtensionSet; friend class internal::LazyField; friend class internal::SwapFieldHelper;