Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/google/protobuf/extension_set.cc
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,19 @@ void ExtensionSet::RegisterMessageExtension(const MessageLite* extendee,
type == WireFormatLite::TYPE_GROUP);
ExtensionInfo info(extendee, number, type, is_repeated, is_packed,
verify_func, is_lazy);
#ifndef PROTOBUF_MESSAGE_GLOBALS
info.message_info = {prototype,
#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES)
prototype->GetTcParseTable()
#else
nullptr
#endif
};
#else // PROTOBUF_MESSAGE_GLOBALS
ABSL_DCHECK_NE(prototype, nullptr);
info.message_info = {
internal::MessageGlobalsBase::FromDefaultInstance(prototype)};
#endif // PROTOBUF_MESSAGE_GLOBALS
Register(info);
}

Expand Down Expand Up @@ -1830,7 +1836,7 @@ const MessageLite* ExtensionSet::GetPrototypeForLazyMessage(
&extension_info, &was_packed_on_wire)) {
return nullptr;
}
return extension_info.message_info.prototype;
return extension_info.message_info.GetPrototype();
}

uint8_t*
Expand Down
42 changes: 39 additions & 3 deletions src/google/protobuf/extension_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <vector>

#include "absl/log/absl_log.h"
#include "google/protobuf/generated_message_util.h"

#include "google/protobuf/stubs/common.h"
#include "absl/base/casts.h"
Expand Down Expand Up @@ -167,18 +168,53 @@ struct ExtensionInfo {
};

struct MessageInfo {
#ifdef PROTOBUF_MESSAGE_GLOBALS
const internal::MessageGlobalsBase* globals = nullptr;
#else
const MessageLite* prototype = nullptr;
// The TcParse table used for this object.
// Never null. (except in platforms that don't constant initialize default
// instances)
// The TcParse table used for this object. Never null. (except in platforms
// that don't constant initialize default instances)
const internal::TcParseTableBase* tc_table = nullptr;
#endif

// Create from prototype
static MessageInfo Create(const MessageLite* prototype) {
const internal::TcParseTableBase* tc_table =
internal::PrivateAccess::GetTcParseTable(prototype);
#ifdef PROTOBUF_MESSAGE_GLOBALS
ABSL_DCHECK_NE(tc_table, nullptr);
return {internal::MessageGlobalsBase::FromDefaultInstance(prototype)};
#else
return {prototype, tc_table};
#endif
}

const MessageLite* GetPrototype() const {
#ifdef PROTOBUF_MESSAGE_GLOBALS
return internal::MessageGlobalsBase::ToDefaultInstance(globals);
#else
return prototype;
#endif
}

const internal::TcParseTableBase* GetTcTable() const {
#ifdef PROTOBUF_MESSAGE_GLOBALS
return internal::MessageGlobalsBase::ToParseTableBase(globals);
#else
return tc_table;
#endif
}

const ClassData* GetClassData() const {
#ifdef PROTOBUF_MESSAGE_GLOBALS
return internal::MessageGlobalsBase::GetClassData(globals);
#else // !PROTOBUF_MESSAGE_GLOBALS
#ifdef PROTOBUF_CONSTINIT_DEFAULT_INSTANCES
return tc_table->class_data;
#else
return google::protobuf::internal::GetClassData(*prototype);
#endif
#endif // !PROTOBUF_MESSAGE_GLOBALS
}
};

Expand Down
11 changes: 6 additions & 5 deletions src/google/protobuf/extension_set_heavy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -258,13 +258,14 @@ bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
output->is_packed = extension->is_packed();
output->descriptor = extension;
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)
output->message_info = ExtensionInfo::MessageInfo::Create(
factory_->GetPrototype(extension->message_type()));
ABSL_CHECK_NE(output->message_info.GetPrototype(), nullptr)
<< "Extension factory's GetPrototype() returned nullptr; extension: "
<< extension->full_name();
ABSL_CHECK_NE(output->message_info.GetTcTable(), nullptr)
<< "Extension factory's GetTcTable() returned nullptr; extension: "
<< extension->full_name();

} else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
output->enum_validity_check.func = ValidateEnumUsingDescriptor;
Expand Down
8 changes: 5 additions & 3 deletions src/google/protobuf/extension_set_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ const char* ExtensionSet::ParseFieldWithExtensionInfo(
? AddMessage(arena, number, WireFormatLite::TYPE_GROUP,
info.message_info.GetClassData(), info.descriptor)
: MutableMessage(arena, number, WireFormatLite::TYPE_GROUP,
*info.message_info.prototype, info.descriptor);
*info.message_info.GetPrototype(),
info.descriptor);
uint32_t tag = (number << 3) + WireFormatLite::WIRETYPE_START_GROUP;
return ctx->ParseGroup(value, ptr, tag);
}
Expand All @@ -180,7 +181,8 @@ const char* ExtensionSet::ParseFieldWithExtensionInfo(
? AddMessage(arena, number, WireFormatLite::TYPE_MESSAGE,
info.message_info.GetClassData(), info.descriptor)
: MutableMessage(arena, number, WireFormatLite::TYPE_MESSAGE,
*info.message_info.prototype, info.descriptor);
*info.message_info.GetPrototype(),
info.descriptor);
return ctx->ParseMessage(value, ptr);
}
}
Expand Down Expand Up @@ -224,7 +226,7 @@ const char* ExtensionSet::ParseMessageSetItemTmpl(
extension.message_info.GetClassData(),
extension.descriptor)
: MutableMessage(arena, type_id, WireFormatLite::TYPE_MESSAGE,
*extension.message_info.prototype,
*extension.message_info.GetPrototype(),
extension.descriptor);

const char* p;
Expand Down
11 changes: 11 additions & 0 deletions src/google/protobuf/generated_message_reflection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3823,6 +3823,17 @@ const internal::TcParseTableBase* Reflection::CreateTcParseTable() const {
byte_size)
<< "message = " << descriptor_->full_name();

#ifdef PROTOBUF_MESSAGE_GLOBALS
// DynamicMessage's parse table is lazily created and its class data should be
// updated to point to the parse table.
ABSL_CHECK_NE(message_factory_, nullptr);
const MessageLite* prototype = message_factory_->GetPrototype(descriptor_);
// const_cast is unfortunate but acceptable as we own the type.
auto* mutable_globals = MessageGlobalsBase::FromDefaultInstance(
const_cast<MessageLite*>(prototype));
ABSL_DCHECK(!mutable_globals->GetClassData()->full().is_lite);
mutable_globals->SetTcParseTableForDynamicMessage(res);
#endif
return res;
}

Expand Down
5 changes: 5 additions & 0 deletions src/google/protobuf/generated_message_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,11 @@ struct PrivateAccess {
return T::InternalGenerateParseTable_(class_data);
}

inline static const internal::TcParseTableBase* GetTcParseTable(
const MessageLite* msg) {
return msg->GetTcParseTable();
}

static internal::ExtensionSet* GetExtensionSet(MessageLite* msg);
static const internal::ExtensionSet* GetExtensionSet(const MessageLite* msg);

Expand Down
11 changes: 11 additions & 0 deletions src/google/protobuf/message_lite.h
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ struct PROTOBUF_EXPORT ClassDataFull : ClassData {
}

constexpr const ClassData* base() const { return this; }
ClassData* mutable_base() { return this; }

// Accessors for reflection related data (ClassDataFull only).
const Reflection* reflection() const { return reflection_data()->reflection; }
Expand Down Expand Up @@ -664,6 +665,11 @@ struct MessageGlobalsBase {
reinterpret_cast<const char*>(default_instance) - OffsetToDefault());
}

static MessageGlobalsBase* FromDefaultInstance(void* default_instance) {
return reinterpret_cast<MessageGlobalsBase*>(
reinterpret_cast<char*>(default_instance) - OffsetToDefault());
}

static constexpr const ClassData* GetClassData(const void* globals) {
return static_cast<const MessageGlobalsBase*>(globals)->class_data.base();
}
Expand All @@ -678,6 +684,11 @@ struct MessageGlobalsBase {
return globals->class_data.tc_table;
}

void SetTcParseTableForDynamicMessage(
const internal::TcParseTableBase* tc_table) {
class_data.mutable_base()->tc_table = tc_table;
}

// It also aliases to ClassDataLite.
ClassDataFull class_data;
};
Expand Down
Loading