Decouple extension registration from the extension identifier definition.

Collect all static initializers in a single expression at the end of the file.
This reduces code bloat, and provides a way to customize the
registration for weak descriptor messages.

PiperOrigin-RevId: 588127128
pull/14956/head
Protobuf Team Bot 1 year ago committed by Copybara-Service
parent a8c3eb7fa5
commit 7253cd98cc
  1. 117
      src/google/protobuf/compiler/cpp/extension.cc
  2. 2
      src/google/protobuf/compiler/cpp/extension.h
  3. 82
      src/google/protobuf/compiler/cpp/file.cc
  4. 8
      src/google/protobuf/compiler/cpp/file.h
  5. 20
      src/google/protobuf/compiler/java/java_features.pb.cc
  6. 7
      src/google/protobuf/compiler/plugin.pb.cc
  7. 2
      src/google/protobuf/cpp_features.pb.cc
  8. 9
      src/google/protobuf/descriptor.cc
  9. 149
      src/google/protobuf/extension_set.h
  10. 22
      src/google/protobuf/generated_message_reflection.cc
  11. 2
      src/google/protobuf/generated_message_reflection.h

@ -26,8 +26,6 @@ namespace protobuf {
namespace compiler {
namespace cpp {
using ::google::protobuf::internal::cpp::IsLazilyInitializedFile;
ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
const Options& options,
MessageSCCAnalyzer* scc_analyzer)
@ -68,6 +66,7 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
variables_["constant_name"] = FieldConstantName(descriptor_);
variables_["field_type"] =
absl::StrCat(static_cast<int>(descriptor_->type()));
variables_["repeated"] = descriptor_->is_repeated() ? "true" : "false";
variables_["packed"] = descriptor_->is_packed() ? "true" : "false";
variables_["dllexport_decl"] = options.dllexport_decl;
@ -122,8 +121,8 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* p) {
} else if (descriptor_->message_type()) {
// We have to initialize the default instance for extensions at
// registration time.
return absl::StrCat(FieldMessageTypeName(descriptor_, options_),
"::default_instance()");
return absl::StrCat("&", QualifiedDefaultInstanceName(
descriptor_->message_type(), options_));
} else {
return DefaultValue(options_, descriptor_);
}
@ -162,58 +161,13 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* p) {
}},
{"define_extension_id",
[&] {
if (IsLazilyInitializedFile(descriptor_->file()->name())) {
p->Emit(R"cc(
PROTOBUF_CONSTINIT$ dllexport_decl$
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::
ExtensionIdentifier<$extendee$, ::_pbi::$type_traits$,
$field_type$, $packed$>
$scoped_name$($constant_name$);
)cc");
return;
}
bool should_verify =
// Only verify msgs.
descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
// Options say to verify.
ShouldVerify(descriptor_->message_type(), options_,
scc_analyzer_) &&
ShouldVerify(descriptor_->containing_type(), options_,
scc_analyzer_);
if (!should_verify) {
p->Emit(R"cc(
$dllexport_decl $PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::
ExtensionIdentifier<$extendee$, ::_pbi::$type_traits$,
$field_type$, $packed$>
$scoped_name$($constant_name$, $default_str$);
)cc");
return;
}
const auto& options = descriptor_->options();
if (options.has_lazy()) {
p->Emit(
{{"is_lazy", options.lazy() ? "kLazy" : "kEager"}},
R"cc(
$dllexport_decl $PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::
ExtensionIdentifier<$extendee$, ::_pbi::$type_traits$,
$field_type$, $packed$>
$scoped_name$($constant_name$, $default_str$,
&$message_type$::InternalVerify,
::_pbi::LazyAnnotation::$is_lazy$);
)cc");
} else {
p->Emit(
R"cc(
$dllexport_decl $PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::
ExtensionIdentifier<$extendee$, ::_pbi::$type_traits$,
$field_type$, $packed$>
$scoped_name$($constant_name$, $default_str$,
&$message_type$::InternalVerify);
)cc");
}
p->Emit(R"cc(
PROTOBUF_CONSTINIT$ dllexport_decl$
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::
ExtensionIdentifier<$extendee$, ::_pbi::$type_traits$,
$field_type$, $packed$>
$scoped_name$($constant_name$, $default_str$);
)cc");
}},
},
R"cc(
@ -223,6 +177,57 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* p) {
)cc");
}
void ExtensionGenerator::GenerateRegistration(io::Printer* p) {
auto vars = p->WithVars(variables_);
switch (descriptor_->cpp_type()) {
case FieldDescriptor::CPPTYPE_ENUM:
p->Emit({{"enum_name", ClassName(descriptor_->enum_type(), true)}},
R"cc(
::_pbi::ExtensionSet::RegisterEnumExtension(
&$extendee$::default_instance(), $number$, $field_type$,
$repeated$, $packed$, $enum_name$_IsValid),
)cc");
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
p->Emit({{"verify",
[&] {
const bool should_verify =
// Only verify msgs.
descriptor_->cpp_type() ==
FieldDescriptor::CPPTYPE_MESSAGE &&
// Options say to verify.
ShouldVerify(descriptor_->message_type(), options_,
scc_analyzer_) &&
ShouldVerify(descriptor_->containing_type(), options_,
scc_analyzer_);
if (should_verify) {
p->Emit("&$message_type$::InternalVerify,");
} else {
p->Emit("nullptr,");
}
}},
{"message_type", FieldMessageTypeName(descriptor_, options_)},
{"lazy", descriptor_->options().has_lazy()
? descriptor_->options().lazy() ? "kLazy" : "kEager"
: "kUndefined"}},
R"cc(
::_pbi::ExtensionSet::RegisterMessageExtension(
&$extendee$::default_instance(), $number$, $field_type$,
$repeated$, $packed$, &$message_type$::default_instance(),
$verify$, ::_pbi::LazyAnnotation::$lazy$),
)cc");
break;
default:
p->Emit(
R"cc(
::_pbi::ExtensionSet::RegisterExtension(
&$extendee$::default_instance(), $number$, $field_type$,
$repeated$, $packed$),
)cc");
break;
}
}
} // namespace cpp
} // namespace compiler
} // namespace protobuf

@ -56,6 +56,8 @@ class PROTOC_EXPORT ExtensionGenerator {
// Source file stuff.
void GenerateDefinition(io::Printer* p);
void GenerateRegistration(io::Printer* p);
bool IsScoped() const;
private:

@ -809,6 +809,23 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* p) {
)cc");
}
void FileGenerator::GenerateStaticInitializer(io::Printer* p) {
if (static_initializers_.empty()) return;
p->Emit({{"expr",
[&] {
for (auto& init : static_initializers_) {
init(p);
}
}}},
R"cc(
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
static ::std::false_type _static_init_ PROTOBUF_UNUSED =
($expr$, ::std::false_type{});
)cc");
// Reset the vector because we might be generating many files.
static_initializers_.clear();
}
void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* p) {
auto v = p->WithVars(FileVars(file_, options_));
GenerateSourceIncludes(p);
@ -816,6 +833,10 @@ void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* p) {
NamespaceOpener ns(Namespace(file_, options_), p);
extension_generators_[idx]->GenerateDefinition(p);
static_initializers_.push_back([this, idx](auto* p) {
extension_generators_[idx]->GenerateRegistration(p);
});
GenerateStaticInitializer(p);
}
void FileGenerator::GenerateGlobalSource(io::Printer* p) {
@ -895,8 +916,14 @@ void FileGenerator::GenerateSource(io::Printer* p) {
}
// Define extensions.
const auto is_lazily_init = IsLazilyInitializedFile(file_->name());
for (int i = 0; i < extension_generators_.size(); ++i) {
extension_generators_[i]->GenerateDefinition(p);
if (!is_lazily_init) {
static_initializers_.push_back([&, i](auto* p) {
extension_generators_[i]->GenerateRegistration(p);
});
}
}
p->Emit(R"cc(
@ -919,6 +946,8 @@ void FileGenerator::GenerateSource(io::Printer* p) {
UnmuteWuninitialized(p);
}
GenerateStaticInitializer(p);
IncludeFile("third_party/protobuf/port_undef.inc", p);
}
@ -1223,41 +1252,24 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) {
// pull in a lot of unnecessary code that can't be stripped by --gc-sections.
// Descriptor initialization will still be performed lazily when it's needed.
if (!IsLazilyInitializedFile(file_->name())) {
p->Emit(
{
{"dummy", UniqueName("dynamic_init_dummy", file_, options_)},
{"desc_table_expr",
[&] {
std::vector<const Descriptor*> pinned_messages;
if (UsingImplicitWeakDescriptor(file_, options_)) {
pinned_messages =
GetMessagesToPinGloballyForWeakDescriptors(file_);
}
if (pinned_messages.empty()) {
p->Emit("&$desc_table$");
} else {
p->Emit({{"pinned",
[&] {
for (const auto* pinned : pinned_messages) {
p->Emit(
{
{"default", QualifiedDefaultInstanceName(
pinned, options_)},
},
R"cc(
::_pbi::StrongPointer(&$default$),
)cc");
}
}}},
"($pinned$, &$desc_table$)");
}
}},
},
R"cc(
// Force running AddDescriptors() at dynamic initialization time.
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
static ::_pbi::AddDescriptorsRunner $dummy$($desc_table_expr$);
)cc");
if (UsingImplicitWeakDescriptor(file_, options_)) {
for (auto* pinned : GetMessagesToPinGloballyForWeakDescriptors(file_)) {
static_initializers_.push_back([this, pinned](auto* p) {
p->Emit(
{
{"default", QualifiedDefaultInstanceName(pinned, options_)},
},
R"cc(
::_pbi::StrongPointer(&$default$),
)cc");
});
}
}
static_initializers_.push_back([](auto* p) {
p->Emit(R"cc(
::_pbi::AddDescriptors(&$desc_table$),
)cc");
});
}
// However, we must provide a way to force initialize the default instances

@ -19,6 +19,7 @@
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/absl_check.h"
#include "google/protobuf/compiler/cpp/enum.h"
#include "google/protobuf/compiler/cpp/extension.h"
@ -78,6 +79,11 @@ class PROTOC_EXPORT FileGenerator {
void GenerateFile(io::Printer* p, GeneratedFileType file_type,
std::function<void()> cb);
// Generates a static initializers with all the existing values from
// `static_initializers_`.
// They run in `PROTOBUF_ATTRIBUTE_INIT_PRIORITY2` priority.
void GenerateStaticInitializer(io::Printer* p);
// Shared code between the two header generators.
void GenerateSharedHeaderCode(io::Printer* p);
@ -170,6 +176,8 @@ class PROTOC_EXPORT FileGenerator {
absl::flat_hash_set<const FileDescriptor*> weak_deps_;
std::vector<absl::AnyInvocable<void(io::Printer*)>> static_initializers_;
const FileDescriptor* file_;
Options options_;

@ -123,9 +123,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fja
PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_getter() {
return &descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto;
}
// Force running AddDescriptors() at dynamic initialization time.
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto(&descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto);
namespace pb {
const ::google::protobuf::EnumDescriptor* JavaFeatures_Utf8Validation_descriptor() {
::google::protobuf::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto);
@ -371,10 +368,11 @@ void JavaFeatures::InternalSwap(JavaFeatures* PROTOBUF_RESTRICT other) {
&descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_once,
file_level_metadata_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto[0]);
}
PROTOC_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::
ExtensionIdentifier<::google::protobuf::FeatureSet, ::_pbi::MessageTypeTraits< ::pb::JavaFeatures >,
11, false>
java(kJavaFieldNumber, ::pb::JavaFeatures::default_instance());
PROTOBUF_CONSTINIT PROTOC_EXPORT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::
ExtensionIdentifier<::google::protobuf::FeatureSet, ::_pbi::MessageTypeTraits< ::pb::JavaFeatures >,
11, false>
java(kJavaFieldNumber, &::pb::_JavaFeatures_default_instance_);
// @@protoc_insertion_point(namespace_scope)
} // namespace pb
namespace google {
@ -382,4 +380,12 @@ namespace protobuf {
} // namespace protobuf
} // namespace google
// @@protoc_insertion_point(global_scope)
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
static ::std::false_type _static_init_ PROTOBUF_UNUSED =
(::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto),
::_pbi::ExtensionSet::RegisterMessageExtension(
&::google::protobuf::FeatureSet::default_instance(), 1001, 11,
false, false, &::pb::JavaFeatures::default_instance(),
nullptr, ::_pbi::LazyAnnotation::kUndefined),
::std::false_type{});
#include "google/protobuf/port_undef.inc"

@ -284,9 +284,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fpl
PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter() {
return &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
}
// Force running AddDescriptors() at dynamic initialization time.
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fplugin_2eproto(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
namespace google {
namespace protobuf {
namespace compiler {
@ -1615,4 +1612,8 @@ namespace protobuf {
} // namespace protobuf
} // namespace google
// @@protoc_insertion_point(global_scope)
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
static ::std::false_type _static_init_ PROTOBUF_UNUSED =
(::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto),
::std::false_type{});
#include "google/protobuf/port_undef.inc"

@ -303,7 +303,7 @@ PROTOBUF_CONSTINIT PROTOBUF_EXPORT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::
ExtensionIdentifier<::google::protobuf::FeatureSet, ::_pbi::MessageTypeTraits< ::pb::CppFeatures >,
11, false>
cpp(kCppFieldNumber);
cpp(kCppFieldNumber, &::pb::_CppFeatures_default_instance_);
// @@protoc_insertion_point(namespace_scope)
} // namespace pb
namespace google {

@ -4610,7 +4610,14 @@ DescriptorBuilder::DescriptorBuilder(
// have to avoid registering these pre-main, because we need to ensure that
// the linker --gc-sections step can strip out the full runtime if it is
// unused.
pb::cpp.LazyRegister();
PROTOBUF_UNUSED static std::true_type lazy_register =
(internal::ExtensionSet::RegisterMessageExtension(
&FeatureSet::default_instance(), pb::cpp.number(),
FieldDescriptor::TYPE_MESSAGE, false, false,
&pb::CppFeatures::default_instance(),
nullptr,
internal::LazyAnnotation::kUndefined),
std::true_type{});
}
DescriptorBuilder::~DescriptorBuilder() {}

@ -1003,8 +1003,6 @@ inline void ExtensionSet::AddString(int number, FieldType type,
// static inline MutableType Add(int number, ExtensionSet* set);
// This is used by the ExtensionIdentifier constructor to register
// the extension at dynamic initialization.
// template <typename ExtendeeT>
// static void Register(int number, FieldType type, bool is_packed);
// };
//
// Not all of these methods make sense for all field types. For example, the
@ -1030,6 +1028,8 @@ class PrimitiveTypeTraits {
public:
typedef Type ConstType;
typedef Type MutableType;
using InitType = ConstType;
static const ConstType& FromInitType(const InitType& v) { return v; }
typedef PrimitiveTypeTraits<Type> Singular;
static constexpr bool kLifetimeBound = false;
@ -1040,11 +1040,6 @@ class PrimitiveTypeTraits {
const ConstType& default_value);
static inline void Set(int number, FieldType field_type, ConstType value,
ExtensionSet* set);
template <typename ExtendeeT>
static void Register(int number, FieldType type, bool is_packed) {
ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
type, false, is_packed);
}
};
template <typename Type>
@ -1052,6 +1047,8 @@ class RepeatedPrimitiveTypeTraits {
public:
typedef Type ConstType;
typedef Type MutableType;
using InitType = ConstType;
static const ConstType& FromInitType(const InitType& v) { return v; }
typedef RepeatedPrimitiveTypeTraits<Type> Repeated;
static constexpr bool kLifetimeBound = false;
@ -1074,11 +1071,6 @@ class RepeatedPrimitiveTypeTraits {
ExtensionSet* set);
static const RepeatedFieldType* GetDefaultRepeatedField();
template <typename ExtendeeT>
static void Register(int number, FieldType type, bool is_packed) {
ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
type, true, is_packed);
}
};
class PROTOBUF_EXPORT RepeatedPrimitiveDefaults {
@ -1178,6 +1170,8 @@ class PROTOBUF_EXPORT StringTypeTraits {
public:
typedef const std::string& ConstType;
typedef std::string* MutableType;
using InitType = ConstType;
static ConstType FromInitType(InitType v) { return v; }
typedef StringTypeTraits Singular;
static constexpr bool kLifetimeBound = true;
@ -1197,17 +1191,14 @@ class PROTOBUF_EXPORT StringTypeTraits {
ExtensionSet* set) {
return set->MutableString(number, field_type, nullptr);
}
template <typename ExtendeeT>
static void Register(int number, FieldType type, bool is_packed) {
ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
type, false, is_packed);
}
};
class PROTOBUF_EXPORT RepeatedStringTypeTraits {
public:
typedef const std::string& ConstType;
typedef std::string* MutableType;
using InitType = ConstType;
static ConstType FromInitType(InitType v) { return v; }
typedef RepeatedStringTypeTraits Repeated;
static constexpr bool kLifetimeBound = true;
@ -1254,12 +1245,6 @@ class PROTOBUF_EXPORT RepeatedStringTypeTraits {
static const RepeatedFieldType* GetDefaultRepeatedField();
template <typename ExtendeeT>
static void Register(int number, FieldType type, bool is_packed) {
ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number,
type, true, is_packed);
}
private:
static void InitializeDefaultRepeatedFields();
static void DestroyDefaultRepeatedFields();
@ -1275,6 +1260,8 @@ class EnumTypeTraits {
public:
typedef Type ConstType;
typedef Type MutableType;
using InitType = ConstType;
static const ConstType& FromInitType(const InitType& v) { return v; }
typedef EnumTypeTraits<Type, IsValid> Singular;
static constexpr bool kLifetimeBound = false;
@ -1292,11 +1279,6 @@ class EnumTypeTraits {
ABSL_DCHECK(IsValid(value));
set->SetEnum(number, field_type, value, nullptr);
}
template <typename ExtendeeT>
static void Register(int number, FieldType type, bool is_packed) {
ExtensionSet::RegisterEnumExtension(&ExtendeeT::default_instance(), number,
type, false, is_packed, IsValid);
}
};
template <typename Type, bool IsValid(int)>
@ -1304,6 +1286,8 @@ class RepeatedEnumTypeTraits {
public:
typedef Type ConstType;
typedef Type MutableType;
using InitType = ConstType;
static const ConstType& FromInitType(const InitType& v) { return v; }
typedef RepeatedEnumTypeTraits<Type, IsValid> Repeated;
static constexpr bool kLifetimeBound = false;
@ -1358,11 +1342,6 @@ class RepeatedEnumTypeTraits {
return reinterpret_cast<const RepeatedField<Type>*>(
RepeatedPrimitiveTypeTraits<int32_t>::GetDefaultRepeatedField());
}
template <typename ExtendeeT>
static void Register(int number, FieldType type, bool is_packed) {
ExtensionSet::RegisterEnumExtension(&ExtendeeT::default_instance(), number,
type, true, is_packed, IsValid);
}
};
// -------------------------------------------------------------------
@ -1376,6 +1355,10 @@ class MessageTypeTraits {
public:
typedef const Type& ConstType;
typedef Type* MutableType;
using InitType = const void*;
static ConstType FromInitType(InitType v) {
return *static_cast<const Type*>(v);
}
typedef MessageTypeTraits<Type> Singular;
static constexpr bool kLifetimeBound = true;
@ -1414,21 +1397,6 @@ class MessageTypeTraits {
return static_cast<Type*>(
set->UnsafeArenaReleaseMessage(number, Type::default_instance()));
}
// Some messages won't (can't) be verified; e.g. lite.
template <typename ExtendeeT>
static void Register(int number, FieldType type, bool is_packed) {
ExtensionSet::RegisterMessageExtension(
&ExtendeeT::default_instance(), number, type, false, is_packed,
&Type::default_instance(), nullptr, LazyAnnotation::kUndefined);
}
template <typename ExtendeeT>
static void Register(int number, FieldType type, bool is_packed,
LazyEagerVerifyFnType fn, LazyAnnotation is_lazy) {
ExtensionSet::RegisterMessageExtension(
&ExtendeeT::default_instance(), number, type, false, is_packed,
&Type::default_instance(), fn, is_lazy);
}
};
// Used by WireFormatVerify to extract the verify function from the registry.
@ -1443,6 +1411,10 @@ class RepeatedMessageTypeTraits {
public:
typedef const Type& ConstType;
typedef Type* MutableType;
using InitType = const void*;
static ConstType FromInitType(InitType v) {
return *static_cast<const Type*>(v);
}
typedef RepeatedMessageTypeTraits<Type> Repeated;
static constexpr bool kLifetimeBound = true;
@ -1489,22 +1461,6 @@ class RepeatedMessageTypeTraits {
}
static const RepeatedFieldType* GetDefaultRepeatedField();
// Some messages won't (can't) be verified; e.g. lite.
template <typename ExtendeeT>
static void Register(int number, FieldType type, bool is_packed) {
ExtensionSet::RegisterMessageExtension(
&ExtendeeT::default_instance(), number, type, true, is_packed,
&Type::default_instance(), nullptr, LazyAnnotation::kUndefined);
}
template <typename ExtendeeT>
static void Register(int number, FieldType type, bool is_packed,
LazyEagerVerifyFnType fn, LazyAnnotation is_lazy) {
ExtensionSet::RegisterMessageExtension(
&ExtendeeT::default_instance(), number, type, true, is_packed,
&Type::default_instance(), fn, is_lazy);
}
};
template <typename Type>
@ -1540,79 +1496,28 @@ class ExtensionIdentifier {
typedef TypeTraitsType TypeTraits;
typedef ExtendeeType Extendee;
ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value)
: number_(number), default_value_(default_value) {
Register(number);
}
ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value,
LazyEagerVerifyFnType verify_func,
LazyAnnotation is_lazy = LazyAnnotation::kUndefined)
: number_(number), default_value_(default_value) {
Register(number, verify_func, is_lazy);
}
constexpr ExtensionIdentifier(int number,
typename TypeTraits::InitType default_value)
: number_(number), default_value_(default_value) {}
inline int number() const { return number_; }
typename TypeTraits::ConstType default_value() const {
return default_value_;
}
static void Register(int number) {
TypeTraits::template Register<ExtendeeType>(number, field_type, is_packed);
}
static void Register(int number, LazyEagerVerifyFnType verify_func,
LazyAnnotation is_lazy) {
TypeTraits::template Register<ExtendeeType>(number, field_type, is_packed,
verify_func, is_lazy);
return TypeTraits::FromInitType(default_value_);
}
typename TypeTraits::ConstType const& default_value_ref() const {
return default_value_;
return TypeTraits::FromInitType(default_value_);
}
private:
const int number_;
typename TypeTraits::ConstType default_value_;
typename TypeTraits::InitType default_value_;
};
// -------------------------------------------------------------------
// Generated accessors
// Define a specialization of ExtensionIdentifier for bootstrapped extensions
// that we need to register lazily.
template <>
class ExtensionIdentifier<FeatureSet, MessageTypeTraits<::pb::CppFeatures>, 11,
false> {
public:
using TypeTraits = MessageTypeTraits<::pb::CppFeatures>;
using Extendee = FeatureSet;
explicit constexpr ExtensionIdentifier(int number) : number_(number) {}
int number() const { return number_; }
const ::pb::CppFeatures& default_value() const { return *default_value_; }
template <typename MessageType = ::pb::CppFeatures,
typename ExtendeeType = FeatureSet>
void LazyRegister(
const MessageType& default_instance = MessageType::default_instance(),
LazyEagerVerifyFnType verify_func = nullptr) const {
absl::call_once(once_, [&] {
default_value_ = &default_instance;
MessageTypeTraits<MessageType>::template Register<ExtendeeType>(
number_, 11, false, verify_func, LazyAnnotation::kUndefined);
});
}
const ::pb::CppFeatures& default_value_ref() const { return *default_value_; }
private:
const int number_;
mutable const ::pb::CppFeatures* default_value_ = nullptr;
mutable absl::once_flag once_;
};
} // namespace internal
// Call this function to ensure that this extensions's reflection is linked into

@ -3617,8 +3617,6 @@ struct MetadataOwner {
std::vector<std::pair<const Metadata*, const Metadata*> > metadata_arrays_;
};
void AddDescriptors(const DescriptorTable* table);
void AssignDescriptorsImpl(const DescriptorTable* table, bool eager) {
// Ensure the file descriptor is added to the pool.
{
@ -3706,16 +3704,6 @@ void AddDescriptorsImpl(const DescriptorTable* table) {
MessageFactory::InternalRegisterGeneratedFile(table);
}
void AddDescriptors(const DescriptorTable* table) {
// AddDescriptors is not thread safe. Callers need to ensure calls are
// properly serialized. This function is only called pre-main by global
// descriptors and we can assume single threaded access or it's called
// by AssignDescriptorImpl which uses a mutex to sequence calls.
if (table->is_initialized) return;
table->is_initialized = true;
AddDescriptorsImpl(table);
}
} // namespace
// Separate function because it needs to be a friend of
@ -3731,6 +3719,16 @@ void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) {
namespace internal {
void AddDescriptors(const DescriptorTable* table) {
// AddDescriptors is not thread safe. Callers need to ensure calls are
// properly serialized. This function is only called pre-main by global
// descriptors and we can assume single threaded access or it's called
// by AssignDescriptorImpl which uses a mutex to sequence calls.
if (table->is_initialized) return;
table->is_initialized = true;
AddDescriptorsImpl(table);
}
Metadata AssignDescriptors(const DescriptorTable* (*table)(),
absl::once_flag* once, const Metadata& metadata) {
absl::call_once(*once, [=] {

@ -338,6 +338,8 @@ PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8_t* base,
PROTOBUF_EXPORT void InitializeFileDescriptorDefaultInstances();
PROTOBUF_EXPORT void AddDescriptors(const DescriptorTable* table);
struct PROTOBUF_EXPORT AddDescriptorsRunner {
explicit AddDescriptorsRunner(const DescriptorTable* table);
};

Loading…
Cancel
Save