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 compiler {
namespace cpp { namespace cpp {
using ::google::protobuf::internal::cpp::IsLazilyInitializedFile;
ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
const Options& options, const Options& options,
MessageSCCAnalyzer* scc_analyzer) MessageSCCAnalyzer* scc_analyzer)
@ -68,6 +66,7 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
variables_["constant_name"] = FieldConstantName(descriptor_); variables_["constant_name"] = FieldConstantName(descriptor_);
variables_["field_type"] = variables_["field_type"] =
absl::StrCat(static_cast<int>(descriptor_->type())); absl::StrCat(static_cast<int>(descriptor_->type()));
variables_["repeated"] = descriptor_->is_repeated() ? "true" : "false";
variables_["packed"] = descriptor_->is_packed() ? "true" : "false"; variables_["packed"] = descriptor_->is_packed() ? "true" : "false";
variables_["dllexport_decl"] = options.dllexport_decl; variables_["dllexport_decl"] = options.dllexport_decl;
@ -122,8 +121,8 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* p) {
} else if (descriptor_->message_type()) { } else if (descriptor_->message_type()) {
// We have to initialize the default instance for extensions at // We have to initialize the default instance for extensions at
// registration time. // registration time.
return absl::StrCat(FieldMessageTypeName(descriptor_, options_), return absl::StrCat("&", QualifiedDefaultInstanceName(
"::default_instance()"); descriptor_->message_type(), options_));
} else { } else {
return DefaultValue(options_, descriptor_); return DefaultValue(options_, descriptor_);
} }
@ -162,58 +161,13 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* p) {
}}, }},
{"define_extension_id", {"define_extension_id",
[&] { [&] {
if (IsLazilyInitializedFile(descriptor_->file()->name())) { p->Emit(R"cc(
p->Emit(R"cc( PROTOBUF_CONSTINIT$ dllexport_decl$
PROTOBUF_CONSTINIT$ dllexport_decl$ PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi:: ExtensionIdentifier<$extendee$, ::_pbi::$type_traits$,
ExtensionIdentifier<$extendee$, ::_pbi::$type_traits$, $field_type$, $packed$>
$field_type$, $packed$> $scoped_name$($constant_name$, $default_str$);
$scoped_name$($constant_name$); )cc");
)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");
}
}}, }},
}, },
R"cc( R"cc(
@ -223,6 +177,57 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* p) {
)cc"); )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 cpp
} // namespace compiler } // namespace compiler
} // namespace protobuf } // namespace protobuf

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

@ -809,6 +809,23 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* p) {
)cc"); )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) { void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* p) {
auto v = p->WithVars(FileVars(file_, options_)); auto v = p->WithVars(FileVars(file_, options_));
GenerateSourceIncludes(p); GenerateSourceIncludes(p);
@ -816,6 +833,10 @@ void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* p) {
NamespaceOpener ns(Namespace(file_, options_), p); NamespaceOpener ns(Namespace(file_, options_), p);
extension_generators_[idx]->GenerateDefinition(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) { void FileGenerator::GenerateGlobalSource(io::Printer* p) {
@ -895,8 +916,14 @@ void FileGenerator::GenerateSource(io::Printer* p) {
} }
// Define extensions. // Define extensions.
const auto is_lazily_init = IsLazilyInitializedFile(file_->name());
for (int i = 0; i < extension_generators_.size(); ++i) { for (int i = 0; i < extension_generators_.size(); ++i) {
extension_generators_[i]->GenerateDefinition(p); 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( p->Emit(R"cc(
@ -919,6 +946,8 @@ void FileGenerator::GenerateSource(io::Printer* p) {
UnmuteWuninitialized(p); UnmuteWuninitialized(p);
} }
GenerateStaticInitializer(p);
IncludeFile("third_party/protobuf/port_undef.inc", 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. // 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. // Descriptor initialization will still be performed lazily when it's needed.
if (!IsLazilyInitializedFile(file_->name())) { if (!IsLazilyInitializedFile(file_->name())) {
p->Emit( if (UsingImplicitWeakDescriptor(file_, options_)) {
{ for (auto* pinned : GetMessagesToPinGloballyForWeakDescriptors(file_)) {
{"dummy", UniqueName("dynamic_init_dummy", file_, options_)}, static_initializers_.push_back([this, pinned](auto* p) {
{"desc_table_expr", p->Emit(
[&] { {
std::vector<const Descriptor*> pinned_messages; {"default", QualifiedDefaultInstanceName(pinned, options_)},
if (UsingImplicitWeakDescriptor(file_, options_)) { },
pinned_messages = R"cc(
GetMessagesToPinGloballyForWeakDescriptors(file_); ::_pbi::StrongPointer(&$default$),
} )cc");
if (pinned_messages.empty()) { });
p->Emit("&$desc_table$"); }
} else { }
p->Emit({{"pinned", static_initializers_.push_back([](auto* p) {
[&] { p->Emit(R"cc(
for (const auto* pinned : pinned_messages) { ::_pbi::AddDescriptors(&$desc_table$),
p->Emit( )cc");
{ });
{"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");
} }
// However, we must provide a way to force initialize the default instances // 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_map.h"
#include "absl/container/flat_hash_set.h" #include "absl/container/flat_hash_set.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/absl_check.h" #include "absl/log/absl_check.h"
#include "google/protobuf/compiler/cpp/enum.h" #include "google/protobuf/compiler/cpp/enum.h"
#include "google/protobuf/compiler/cpp/extension.h" #include "google/protobuf/compiler/cpp/extension.h"
@ -78,6 +79,11 @@ class PROTOC_EXPORT FileGenerator {
void GenerateFile(io::Printer* p, GeneratedFileType file_type, void GenerateFile(io::Printer* p, GeneratedFileType file_type,
std::function<void()> cb); 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. // Shared code between the two header generators.
void GenerateSharedHeaderCode(io::Printer* p); void GenerateSharedHeaderCode(io::Printer* p);
@ -170,6 +176,8 @@ class PROTOC_EXPORT FileGenerator {
absl::flat_hash_set<const FileDescriptor*> weak_deps_; absl::flat_hash_set<const FileDescriptor*> weak_deps_;
std::vector<absl::AnyInvocable<void(io::Printer*)>> static_initializers_;
const FileDescriptor* file_; const FileDescriptor* file_;
Options options_; 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() { 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; 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 { namespace pb {
const ::google::protobuf::EnumDescriptor* JavaFeatures_Utf8Validation_descriptor() { const ::google::protobuf::EnumDescriptor* JavaFeatures_Utf8Validation_descriptor() {
::google::protobuf::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto); ::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, &descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_once,
file_level_metadata_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto[0]); file_level_metadata_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto[0]);
} }
PROTOC_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi:: PROTOBUF_CONSTINIT PROTOC_EXPORT
ExtensionIdentifier<::google::protobuf::FeatureSet, ::_pbi::MessageTypeTraits< ::pb::JavaFeatures >, PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::
11, false> ExtensionIdentifier<::google::protobuf::FeatureSet, ::_pbi::MessageTypeTraits< ::pb::JavaFeatures >,
java(kJavaFieldNumber, ::pb::JavaFeatures::default_instance()); 11, false>
java(kJavaFieldNumber, &::pb::_JavaFeatures_default_instance_);
// @@protoc_insertion_point(namespace_scope) // @@protoc_insertion_point(namespace_scope)
} // namespace pb } // namespace pb
namespace google { namespace google {
@ -382,4 +380,12 @@ namespace protobuf {
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
// @@protoc_insertion_point(global_scope) // @@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" #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() { PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter() {
return &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto; 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 google {
namespace protobuf { namespace protobuf {
namespace compiler { namespace compiler {
@ -1615,4 +1612,8 @@ namespace protobuf {
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
// @@protoc_insertion_point(global_scope) // @@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" #include "google/protobuf/port_undef.inc"

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

@ -4610,7 +4610,14 @@ DescriptorBuilder::DescriptorBuilder(
// have to avoid registering these pre-main, because we need to ensure that // 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 // the linker --gc-sections step can strip out the full runtime if it is
// unused. // 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() {} DescriptorBuilder::~DescriptorBuilder() {}

@ -1003,8 +1003,6 @@ inline void ExtensionSet::AddString(int number, FieldType type,
// static inline MutableType Add(int number, ExtensionSet* set); // static inline MutableType Add(int number, ExtensionSet* set);
// This is used by the ExtensionIdentifier constructor to register // This is used by the ExtensionIdentifier constructor to register
// the extension at dynamic initialization. // 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 // Not all of these methods make sense for all field types. For example, the
@ -1030,6 +1028,8 @@ class PrimitiveTypeTraits {
public: public:
typedef Type ConstType; typedef Type ConstType;
typedef Type MutableType; typedef Type MutableType;
using InitType = ConstType;
static const ConstType& FromInitType(const InitType& v) { return v; }
typedef PrimitiveTypeTraits<Type> Singular; typedef PrimitiveTypeTraits<Type> Singular;
static constexpr bool kLifetimeBound = false; static constexpr bool kLifetimeBound = false;
@ -1040,11 +1040,6 @@ class PrimitiveTypeTraits {
const ConstType& default_value); const ConstType& default_value);
static inline void Set(int number, FieldType field_type, ConstType value, static inline void Set(int number, FieldType field_type, ConstType value,
ExtensionSet* set); 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> template <typename Type>
@ -1052,6 +1047,8 @@ class RepeatedPrimitiveTypeTraits {
public: public:
typedef Type ConstType; typedef Type ConstType;
typedef Type MutableType; typedef Type MutableType;
using InitType = ConstType;
static const ConstType& FromInitType(const InitType& v) { return v; }
typedef RepeatedPrimitiveTypeTraits<Type> Repeated; typedef RepeatedPrimitiveTypeTraits<Type> Repeated;
static constexpr bool kLifetimeBound = false; static constexpr bool kLifetimeBound = false;
@ -1074,11 +1071,6 @@ class RepeatedPrimitiveTypeTraits {
ExtensionSet* set); ExtensionSet* set);
static const RepeatedFieldType* GetDefaultRepeatedField(); 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 { class PROTOBUF_EXPORT RepeatedPrimitiveDefaults {
@ -1178,6 +1170,8 @@ class PROTOBUF_EXPORT StringTypeTraits {
public: public:
typedef const std::string& ConstType; typedef const std::string& ConstType;
typedef std::string* MutableType; typedef std::string* MutableType;
using InitType = ConstType;
static ConstType FromInitType(InitType v) { return v; }
typedef StringTypeTraits Singular; typedef StringTypeTraits Singular;
static constexpr bool kLifetimeBound = true; static constexpr bool kLifetimeBound = true;
@ -1197,17 +1191,14 @@ class PROTOBUF_EXPORT StringTypeTraits {
ExtensionSet* set) { ExtensionSet* set) {
return set->MutableString(number, field_type, nullptr); 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 { class PROTOBUF_EXPORT RepeatedStringTypeTraits {
public: public:
typedef const std::string& ConstType; typedef const std::string& ConstType;
typedef std::string* MutableType; typedef std::string* MutableType;
using InitType = ConstType;
static ConstType FromInitType(InitType v) { return v; }
typedef RepeatedStringTypeTraits Repeated; typedef RepeatedStringTypeTraits Repeated;
static constexpr bool kLifetimeBound = true; static constexpr bool kLifetimeBound = true;
@ -1254,12 +1245,6 @@ class PROTOBUF_EXPORT RepeatedStringTypeTraits {
static const RepeatedFieldType* GetDefaultRepeatedField(); 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: private:
static void InitializeDefaultRepeatedFields(); static void InitializeDefaultRepeatedFields();
static void DestroyDefaultRepeatedFields(); static void DestroyDefaultRepeatedFields();
@ -1275,6 +1260,8 @@ class EnumTypeTraits {
public: public:
typedef Type ConstType; typedef Type ConstType;
typedef Type MutableType; typedef Type MutableType;
using InitType = ConstType;
static const ConstType& FromInitType(const InitType& v) { return v; }
typedef EnumTypeTraits<Type, IsValid> Singular; typedef EnumTypeTraits<Type, IsValid> Singular;
static constexpr bool kLifetimeBound = false; static constexpr bool kLifetimeBound = false;
@ -1292,11 +1279,6 @@ class EnumTypeTraits {
ABSL_DCHECK(IsValid(value)); ABSL_DCHECK(IsValid(value));
set->SetEnum(number, field_type, value, nullptr); 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)> template <typename Type, bool IsValid(int)>
@ -1304,6 +1286,8 @@ class RepeatedEnumTypeTraits {
public: public:
typedef Type ConstType; typedef Type ConstType;
typedef Type MutableType; typedef Type MutableType;
using InitType = ConstType;
static const ConstType& FromInitType(const InitType& v) { return v; }
typedef RepeatedEnumTypeTraits<Type, IsValid> Repeated; typedef RepeatedEnumTypeTraits<Type, IsValid> Repeated;
static constexpr bool kLifetimeBound = false; static constexpr bool kLifetimeBound = false;
@ -1358,11 +1342,6 @@ class RepeatedEnumTypeTraits {
return reinterpret_cast<const RepeatedField<Type>*>( return reinterpret_cast<const RepeatedField<Type>*>(
RepeatedPrimitiveTypeTraits<int32_t>::GetDefaultRepeatedField()); 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: public:
typedef const Type& ConstType; typedef const Type& ConstType;
typedef Type* MutableType; typedef Type* MutableType;
using InitType = const void*;
static ConstType FromInitType(InitType v) {
return *static_cast<const Type*>(v);
}
typedef MessageTypeTraits<Type> Singular; typedef MessageTypeTraits<Type> Singular;
static constexpr bool kLifetimeBound = true; static constexpr bool kLifetimeBound = true;
@ -1414,21 +1397,6 @@ class MessageTypeTraits {
return static_cast<Type*>( return static_cast<Type*>(
set->UnsafeArenaReleaseMessage(number, Type::default_instance())); 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. // Used by WireFormatVerify to extract the verify function from the registry.
@ -1443,6 +1411,10 @@ class RepeatedMessageTypeTraits {
public: public:
typedef const Type& ConstType; typedef const Type& ConstType;
typedef Type* MutableType; typedef Type* MutableType;
using InitType = const void*;
static ConstType FromInitType(InitType v) {
return *static_cast<const Type*>(v);
}
typedef RepeatedMessageTypeTraits<Type> Repeated; typedef RepeatedMessageTypeTraits<Type> Repeated;
static constexpr bool kLifetimeBound = true; static constexpr bool kLifetimeBound = true;
@ -1489,22 +1461,6 @@ class RepeatedMessageTypeTraits {
} }
static const RepeatedFieldType* GetDefaultRepeatedField(); 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> template <typename Type>
@ -1540,79 +1496,28 @@ class ExtensionIdentifier {
typedef TypeTraitsType TypeTraits; typedef TypeTraitsType TypeTraits;
typedef ExtendeeType Extendee; typedef ExtendeeType Extendee;
ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value) constexpr ExtensionIdentifier(int number,
: number_(number), default_value_(default_value) { typename TypeTraits::InitType default_value)
Register(number); : number_(number), default_value_(default_value) {}
}
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);
}
inline int number() const { return number_; } inline int number() const { return number_; }
typename TypeTraits::ConstType default_value() const { typename TypeTraits::ConstType default_value() const {
return default_value_; return TypeTraits::FromInitType(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);
} }
typename TypeTraits::ConstType const& default_value_ref() const { typename TypeTraits::ConstType const& default_value_ref() const {
return default_value_; return TypeTraits::FromInitType(default_value_);
} }
private: private:
const int number_; const int number_;
typename TypeTraits::ConstType default_value_; typename TypeTraits::InitType default_value_;
}; };
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Generated accessors // 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 } // namespace internal
// Call this function to ensure that this extensions's reflection is linked into // 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_; std::vector<std::pair<const Metadata*, const Metadata*> > metadata_arrays_;
}; };
void AddDescriptors(const DescriptorTable* table);
void AssignDescriptorsImpl(const DescriptorTable* table, bool eager) { void AssignDescriptorsImpl(const DescriptorTable* table, bool eager) {
// Ensure the file descriptor is added to the pool. // Ensure the file descriptor is added to the pool.
{ {
@ -3706,16 +3704,6 @@ void AddDescriptorsImpl(const DescriptorTable* table) {
MessageFactory::InternalRegisterGeneratedFile(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 } // namespace
// Separate function because it needs to be a friend of // 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 { 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)(), Metadata AssignDescriptors(const DescriptorTable* (*table)(),
absl::once_flag* once, const Metadata& metadata) { absl::once_flag* once, const Metadata& metadata) {
absl::call_once(*once, [=] { absl::call_once(*once, [=] {

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

Loading…
Cancel
Save