New feature: weak descriptor based types.
This feature allows for tree shaking within a single .proto file, dropping
unused types while still allowing reflection to work for them via the generated
DescriptorPool.
PiperOrigin-RevId: 587066283
diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc
index 0ef0e64..df46703 100644
--- a/src/google/protobuf/compiler/cpp/file.cc
+++ b/src/google/protobuf/compiler/cpp/file.cc
@@ -922,6 +922,26 @@
IncludeFile("third_party/protobuf/port_undef.inc", p);
}
+static std::vector<const Descriptor*>
+GetMessagesToPinGloballyForWeakDescriptors(const FileDescriptor* file) {
+ std::vector<const Descriptor*> out;
+
+ // For simplicity we force pin request/response messages for all
+ // services. The current implementation of services might not do
+ // the pin itself, so it is simpler.
+ // This is a place for improvement in the future.
+ for (int i = 0; i < file->service_count(); ++i) {
+ auto* service = file->service(i);
+ for (int j = 0; j < service->method_count(); ++j) {
+ auto* method = service->method(j);
+ out.push_back(method->input_type());
+ out.push_back(method->output_type());
+ }
+ }
+
+ return out;
+}
+
void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) {
if (!message_generators_.empty()) {
p->Emit({{"len", message_generators_.size()}}, R"cc(
@@ -955,6 +975,8 @@
if (!message_generators_.empty()) {
std::vector<std::pair<size_t, size_t>> offsets;
offsets.reserve(message_generators_.size());
+ bool has_implicit_weak_descriptors =
+ UsingImplicitWeakDescriptor(file_, options_);
p->Emit(
{
@@ -973,19 +995,50 @@
offset += offsets[i].first;
}
}},
- {"defaults",
+ {"weak_defaults",
[&] {
+ if (!has_implicit_weak_descriptors) return;
+ int index = 0;
for (auto& gen : message_generators_) {
p->Emit(
{
+ {"index", index++},
{"ns", Namespace(gen->descriptor(), options_)},
{"class", ClassName(gen->descriptor())},
+ {"section", WeakDefaultWriterSection(gen->descriptor(),
+ options_)},
},
R"cc(
- &$ns$::_$class$_default_instance_._instance,
+ constexpr ::_pbi::WeakDefaultWriter pb_$index$_weak_
+ __attribute__((__nodebug__))
+ __attribute__((section("$section$"))) = {
+ file_default_instances + $index$,
+ &$ns$::_$class$_default_instance_._instance};
)cc");
}
}},
+ {"defaults",
+ [&] {
+ for (auto& gen : message_generators_) {
+ if (has_implicit_weak_descriptors) {
+ p->Emit(R"cc(
+ nullptr,
+ )cc");
+ } else {
+ p->Emit(
+ {
+ {"ns", Namespace(gen->descriptor(), options_)},
+ {"class", ClassName(gen->descriptor())},
+ },
+ R"cc(
+ &$ns$::_$class$_default_instance_._instance,
+ )cc");
+ }
+ }
+ }},
+ // When we have implicit weak descriptors we make the array mutable
+ // for dynamic initialization.
+ {"const", has_implicit_weak_descriptors ? "" : "const"},
},
R"cc(
const ::uint32_t
@@ -999,9 +1052,10 @@
$schemas$,
};
- static const ::_pb::Message* const file_default_instances[] = {
+ static const ::_pb::Message* $const $file_default_instances[] = {
$defaults$,
};
+ $weak_defaults$;
)cc");
} else {
// Ee still need these symbols to exist.
@@ -1169,12 +1223,41 @@
// 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_)}},
- R"cc(
- // Force running AddDescriptors() at dynamic initialization time.
- PROTOBUF_ATTRIBUTE_INIT_PRIORITY2
- static ::_pbi::AddDescriptorsRunner $dummy$(&$desc_table$);
- )cc");
+ 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");
}
// However, we must provide a way to force initialize the default instances
diff --git a/src/google/protobuf/compiler/cpp/generator.cc b/src/google/protobuf/compiler/cpp/generator.cc
index cc0f8af..32d2a2c 100644
--- a/src/google/protobuf/compiler/cpp/generator.cc
+++ b/src/google/protobuf/compiler/cpp/generator.cc
@@ -139,6 +139,8 @@
if (!value.empty()) {
file_options.num_cc_files = std::strtol(value.c_str(), nullptr, 10);
}
+ } else if (key == "descriptor_implicit_weak_messages") {
+ file_options.descriptor_implicit_weak_messages = true;
} else if (key == "proto_h") {
file_options.proto_h = true;
} else if (key == "proto_static_reflection_h") {
diff --git a/src/google/protobuf/compiler/cpp/helpers.cc b/src/google/protobuf/compiler/cpp/helpers.cc
index 7428660..79d4768 100644
--- a/src/google/protobuf/compiler/cpp/helpers.cc
+++ b/src/google/protobuf/compiler/cpp/helpers.cc
@@ -1480,6 +1480,32 @@
return false;
}
+bool UsingImplicitWeakDescriptor(const FileDescriptor* file,
+ const Options& options) {
+ return HasDescriptorMethods(file, options) &&
+ !IsBootstrapProto(options, file) &&
+ options.descriptor_implicit_weak_messages &&
+ !options.opensource_runtime;
+}
+
+std::string WeakDefaultWriterSection(const Descriptor* descriptor,
+ const Options& options) {
+ const auto* file = descriptor->file();
+
+ // To make a compact name we use the index of the object in its parent instead
+ // of its name, recursively until we reach the root.
+ // So the name could be `pb_def_1_2_1_0_HASH` instead of
+ // `pd_def_VeryLongClassName_WithNesting_AndMoreNames_HASH`
+ // We need a know common prefix to merge the sections later on.
+ std::string prefix = "pb_def";
+ do {
+ absl::StrAppend(&prefix, "_", descriptor->index());
+ descriptor = descriptor->containing_type();
+ } while (descriptor != nullptr);
+
+ return UniqueName(prefix, file, options);
+}
+
bool UsingImplicitWeakFields(const FileDescriptor* file,
const Options& options) {
return options.lite_implicit_weak_fields &&
diff --git a/src/google/protobuf/compiler/cpp/helpers.h b/src/google/protobuf/compiler/cpp/helpers.h
index e3e7bf6..5815b4a 100644
--- a/src/google/protobuf/compiler/cpp/helpers.h
+++ b/src/google/protobuf/compiler/cpp/helpers.h
@@ -734,6 +734,60 @@
void ListAllTypesForServices(const FileDescriptor* fd,
std::vector<const Descriptor*>* types);
+// Whether this type should use the implicit weak feature for descriptor based
+// objects.
+//
+// This feature allows tree shaking within a single translation unit by
+// decoupling the messages from the TU-wide `file_default_instances` array.
+// This way there are no static initializers in the TU pointing to any part of
+// the generated classes and they can be GC'd by the linker.
+// Instead, we inject the surviving messages by having `WeakDefaultWriter`
+// objects in a special `pb_defaults` section. The runtime will iterate this
+// section to see the list of all live objects and put them back into the
+// `file_default_instances` array.
+//
+// Any object that gets GC'd will have a `nullptr` in the respective slot in the
+// `file_default_instances` array. The runtime will recognize this and will
+// dynamically generate the object if needed. This logic is in the
+// `GeneratedMessageFactory::GetPrototype`. It will fall back to a
+// `DynamicMessage` for the missing objects.
+// This allows all of reflection to keep working normally, even for types that
+// were dropped. Note that dropping the _classes_ will not drop the descriptor
+// information. The messages are still going to be registered in the generated
+// `DescriptorPool` and will be available via normal `FindMessageTypeByName` and
+// friends.
+//
+// A "pin" is adding dependency edge in the graph for the GC.
+// The `WeakDefaultWriter`, the default instance, and vtable of a message all
+// pin each other. If anyone lives, they all do. This is important.
+// The `WeakDefaultWriter` pins the default instance of the message by using it.
+// The default instance of the message pins the vtable trivially by using it.
+// The vtable pins the `WeakDefaultWriter` by having a StrongPointer into it
+// from any of the virtual functions.
+//
+// All parent messages pin their children.
+// SPEED messages do this implicitly via the TcParseTable, which contain
+// pointers to the submessages.
+// CODE_SIZE messages explicitly add a pin via `StrongPointer` somewhere in
+// their codegen.
+// LITE messages do not participate at all in this feature.
+//
+// For extensions, the identifiers currently pin both the extended and extendee
+// messages. This is the status quo, but not the desired end state which should
+// change in a future update to the feature.
+//
+// For services, the TU unconditionally pins the request/response objects.
+// This is the status quo for simplicitly to avoid modifying the RPC layer. It
+// might be improved in the future.
+bool UsingImplicitWeakDescriptor(const FileDescriptor* file,
+ const Options& options);
+
+// Section name to be used for the DefaultWriter object for implicit weak
+// descriptor objects.
+// See `UsingImplicitWeakDescriptor` above.
+std::string WeakDefaultWriterSection(const Descriptor* descriptor,
+ const Options& options);
+
// Indicates whether we should use implicit weak fields for this file.
bool UsingImplicitWeakFields(const FileDescriptor* file,
const Options& options);
diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc
index e78326f..d5fb7af 100644
--- a/src/google/protobuf/compiler/cpp/message.cc
+++ b/src/google/protobuf/compiler/cpp/message.cc
@@ -2057,30 +2057,50 @@
auto v = p->WithVars(ClassVars(descriptor_, options_));
auto t = p->WithVars(MakeTrackerCalls(descriptor_, options_));
Formatter format(p);
+
+ const auto pin_weak_writer = [&] {
+ if (!UsingImplicitWeakDescriptor(descriptor_->file(), options_)) return;
+ p->Emit({{"index", index_in_file_messages_}},
+ R"cc(
+ ::_pbi::StrongPointer(&pb_$index$_weak_);
+ )cc");
+
+ // For CODE_SIZE types, we need to pin the submessages too.
+ // SPEED types will pin them via the TcParse table automatically.
+ if (HasGeneratedMethods(descriptor_->file(), options_)) return;
+ for (int i = 0; i < descriptor_->field_count(); ++i) {
+ auto* field = descriptor_->field(i);
+ if (field->type() != field->TYPE_MESSAGE) continue;
+ p->Emit(
+ {
+ {"sub_default_name",
+ QualifiedDefaultInstanceName(field->message_type(), options_)},
+ },
+ R"cc(
+ ::_pbi::StrongPointer(&$sub_default_name$);
+ )cc");
+ }
+ };
+
if (IsMapEntryMessage(descriptor_)) {
format(
"$classname$::$classname$() {}\n"
"$classname$::$classname$(::$proto_ns$::Arena* arena)\n"
" : SuperType(arena) {}\n");
if (HasDescriptorMethods(descriptor_->file(), options_)) {
- if (!descriptor_->options().map_entry()) {
- format(
- "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
- "$annotate_reflection$"
- " return ::_pbi::AssignDescriptors(\n"
- " &$desc_table$_getter, &$desc_table$_once,\n"
- " $file_level_metadata$[$1$]);\n"
- "}\n",
- index_in_file_messages_);
- } else {
- format(
- "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
- " return ::_pbi::AssignDescriptors(\n"
- " &$desc_table$_getter, &$desc_table$_once,\n"
- " $file_level_metadata$[$1$]);\n"
- "}\n",
- index_in_file_messages_);
- }
+ p->Emit(
+ {
+ {"pin_weak_writer", pin_weak_writer},
+ {"index", index_in_file_messages_},
+ },
+ R"cc(
+ ::$proto_ns$::Metadata $classname$::GetMetadata() const {
+ $pin_weak_writer$;
+ return ::_pbi::AssignDescriptors(&$desc_table$_getter,
+ &$desc_table$_once,
+ $file_level_metadata$[$index$]);
+ }
+ )cc");
}
return;
}
@@ -2203,24 +2223,20 @@
format("\n");
if (HasDescriptorMethods(descriptor_->file(), options_)) {
- if (!descriptor_->options().map_entry()) {
- format(
- "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
- "$annotate_reflection$"
- " return ::_pbi::AssignDescriptors(\n"
- " &$desc_table$_getter, &$desc_table$_once,\n"
- " $file_level_metadata$[$1$]);\n"
- "}\n",
- index_in_file_messages_);
- } else {
- format(
- "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
- " return ::_pbi::AssignDescriptors(\n"
- " &$desc_table$_getter, &$desc_table$_once,\n"
- " $file_level_metadata$[$1$]);\n"
- "}\n",
- index_in_file_messages_);
- }
+ p->Emit(
+ {
+ {"pin_weak_writer", pin_weak_writer},
+ {"index", index_in_file_messages_},
+ },
+ R"cc(
+ ::$proto_ns$::Metadata $classname$::GetMetadata() const {
+ $annotate_reflection$;
+ $pin_weak_writer$;
+ return ::_pbi::AssignDescriptors(&$desc_table$_getter,
+ &$desc_table$_once,
+ $file_level_metadata$[$index$]);
+ }
+ )cc");
}
if (HasTracker(descriptor_, options_)) {
diff --git a/src/google/protobuf/compiler/cpp/options.h b/src/google/protobuf/compiler/cpp/options.h
index 30be9c0..4d60063 100644
--- a/src/google/protobuf/compiler/cpp/options.h
+++ b/src/google/protobuf/compiler/cpp/options.h
@@ -50,6 +50,7 @@
bool transitive_pb_h = true;
bool annotate_headers = false;
bool lite_implicit_weak_fields = false;
+ bool descriptor_implicit_weak_messages = false;
bool bootstrap = false;
bool opensource_runtime = false;
bool annotate_accessor = false;
diff --git a/src/google/protobuf/compiler/java/java_features.pb.cc b/src/google/protobuf/compiler/java/java_features.pb.cc
index 9c2c10c..7f940e8 100644
--- a/src/google/protobuf/compiler/java/java_features.pb.cc
+++ b/src/google/protobuf/compiler/java/java_features.pb.cc
@@ -367,9 +367,9 @@
}
::google::protobuf::Metadata JavaFeatures::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto[0]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_getter,
+ &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 >,
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index 12f13d0..a782fcc 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -608,9 +608,9 @@
}
::google::protobuf::Metadata Version::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[0]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[0]);
}
// ===================================================================
@@ -953,9 +953,9 @@
}
::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]);
}
// ===================================================================
@@ -1272,9 +1272,9 @@
}
::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[2]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[2]);
}
// ===================================================================
@@ -1602,9 +1602,9 @@
}
::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[3]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[3]);
}
// @@protoc_insertion_point(namespace_scope)
} // namespace compiler
diff --git a/src/google/protobuf/cpp_features.pb.cc b/src/google/protobuf/cpp_features.pb.cc
index 0052cf1..b0f7f30 100644
--- a/src/google/protobuf/cpp_features.pb.cc
+++ b/src/google/protobuf/cpp_features.pb.cc
@@ -295,9 +295,9 @@
}
::google::protobuf::Metadata CppFeatures::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fcpp_5ffeatures_2eproto[0]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fcpp_5ffeatures_2eproto[0]);
}
PROTOBUF_CONSTINIT PROTOBUF_EXPORT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index ea59753..269a8dc 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -2534,9 +2534,9 @@
}
::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[0]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[0]);
}
// ===================================================================
@@ -3122,9 +3122,9 @@
}
::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[1]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[1]);
}
// ===================================================================
@@ -3406,9 +3406,9 @@
}
::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[2]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[2]);
}
// ===================================================================
@@ -3629,9 +3629,9 @@
}
::google::protobuf::Metadata DescriptorProto_ReservedRange::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[3]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[3]);
}
// ===================================================================
@@ -4116,9 +4116,9 @@
}
::google::protobuf::Metadata DescriptorProto::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[4]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[4]);
}
// ===================================================================
@@ -4450,9 +4450,9 @@
}
::google::protobuf::Metadata ExtensionRangeOptions_Declaration::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[5]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[5]);
}
// ===================================================================
@@ -4775,9 +4775,9 @@
}
::google::protobuf::Metadata ExtensionRangeOptions::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[6]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[6]);
}
// ===================================================================
@@ -5300,9 +5300,9 @@
}
::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[7]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[7]);
}
// ===================================================================
@@ -5554,9 +5554,9 @@
}
::google::protobuf::Metadata OneofDescriptorProto::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[8]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[8]);
}
// ===================================================================
@@ -5777,9 +5777,9 @@
}
::google::protobuf::Metadata EnumDescriptorProto_EnumReservedRange::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[9]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[9]);
}
// ===================================================================
@@ -6116,9 +6116,9 @@
}
::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[10]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[10]);
}
// ===================================================================
@@ -6405,9 +6405,9 @@
}
::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[11]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[11]);
}
// ===================================================================
@@ -6689,9 +6689,9 @@
}
::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[12]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[12]);
}
// ===================================================================
@@ -7069,9 +7069,9 @@
}
::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[13]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[13]);
}
// ===================================================================
@@ -7903,9 +7903,9 @@
}
::google::protobuf::Metadata FileOptions::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[14]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[14]);
}
// ===================================================================
@@ -8289,9 +8289,9 @@
}
::google::protobuf::Metadata MessageOptions::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[15]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[15]);
}
// ===================================================================
@@ -8525,9 +8525,9 @@
}
::google::protobuf::Metadata FieldOptions_EditionDefault::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[16]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[16]);
}
// ===================================================================
@@ -9069,9 +9069,9 @@
}
::google::protobuf::Metadata FieldOptions::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[17]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[17]);
}
// ===================================================================
@@ -9329,9 +9329,9 @@
}
::google::protobuf::Metadata OneofOptions::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[18]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[18]);
}
// ===================================================================
@@ -9675,9 +9675,9 @@
}
::google::protobuf::Metadata EnumOptions::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[19]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[19]);
}
// ===================================================================
@@ -10003,9 +10003,9 @@
}
::google::protobuf::Metadata EnumValueOptions::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[20]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[20]);
}
// ===================================================================
@@ -10300,9 +10300,9 @@
}
::google::protobuf::Metadata ServiceOptions::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[21]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[21]);
}
// ===================================================================
@@ -10633,9 +10633,9 @@
}
::google::protobuf::Metadata MethodOptions::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[22]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[22]);
}
// ===================================================================
@@ -10874,9 +10874,9 @@
}
::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[23]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[23]);
}
// ===================================================================
@@ -11263,9 +11263,9 @@
}
::google::protobuf::Metadata UninterpretedOption::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[24]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[24]);
}
// ===================================================================
@@ -11615,9 +11615,9 @@
}
::google::protobuf::Metadata FeatureSet::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[25]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[25]);
}
// ===================================================================
@@ -11867,9 +11867,9 @@
}
::google::protobuf::Metadata FeatureSetDefaults_FeatureSetEditionDefault::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[26]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[26]);
}
// ===================================================================
@@ -12137,9 +12137,9 @@
}
::google::protobuf::Metadata FeatureSetDefaults::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[27]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[27]);
}
// ===================================================================
@@ -12479,9 +12479,9 @@
}
::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[28]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[28]);
}
// ===================================================================
@@ -12665,9 +12665,9 @@
}
::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[29]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[29]);
}
// ===================================================================
@@ -13003,9 +13003,9 @@
}
::google::protobuf::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[30]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[30]);
}
// ===================================================================
@@ -13189,9 +13189,9 @@
}
::google::protobuf::Metadata GeneratedCodeInfo::GetMetadata() const {
- return ::_pbi::AssignDescriptors(
- &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
- file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[31]);
+ return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter,
+ &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once,
+ file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[31]);
}
// @@protoc_insertion_point(namespace_scope)
} // namespace protobuf
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
index 7872866..1dcbe30 100644
--- a/src/google/protobuf/dynamic_message.cc
+++ b/src/google/protobuf/dynamic_message.cc
@@ -627,7 +627,9 @@
const Descriptor* type) {
if (delegate_to_generated_factory_ &&
type->file()->pool() == DescriptorPool::generated_pool()) {
- return MessageFactory::generated_factory()->GetPrototype(type);
+ const Message* result = MessageFactory::TryGetGeneratedPrototype(type);
+ if (result != nullptr) return result;
+ // Otherwise, we will create it dynamically so keep going.
}
const TypeInfo** target = &prototypes_[type];
diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc
index 4893ca8..1bad594 100644
--- a/src/google/protobuf/generated_message_util.cc
+++ b/src/google/protobuf/generated_message_util.cc
@@ -21,6 +21,7 @@
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include "google/protobuf/message_lite.h"
#include "google/protobuf/metadata_lite.h"
+#include "google/protobuf/port.h"
#include "google/protobuf/repeated_field.h"
#include "google/protobuf/wire_format_lite.h"
@@ -48,10 +49,32 @@
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT const EmptyCord empty_cord_;
+#if defined(PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED)
+extern "C" {
+// We add a single dummy writer to guarantee the section is never empty.
+WeakDefaultWriter dummy_writer
+ __attribute__((section("pb_defaults"))) = {&dummy_writer.source, nullptr};
+// When using --descriptor_implicit_weak_messages we expect the writer objects
+// to live in the `pb_defaults` section. We load them all using the
+// __start/__end symbols provided by the linker.
+extern const WeakDefaultWriter __start_pb_defaults;
+extern const WeakDefaultWriter __stop_pb_defaults;
+}
+static void InitWeakDefaults() {
+ StrongPointer(&dummy_writer); // force link the dummy writer.
+ for (auto it = &__start_pb_defaults; it != &__stop_pb_defaults; ++it) {
+ *it->destination = it->source;
+ }
+}
+#else
+void InitWeakDefaults() {}
+#endif
+
PROTOBUF_CONSTINIT std::atomic<bool> init_protobuf_defaults_state{false};
static bool InitProtobufDefaultsImpl() {
fixed_address_empty_string.DefaultConstruct();
OnShutdownDestroyString(fixed_address_empty_string.get_mutable());
+ InitWeakDefaults();
init_protobuf_defaults_state.store(true, std::memory_order_release);
diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h
index 72e6649..4c1258f 100644
--- a/src/google/protobuf/generated_message_util.h
+++ b/src/google/protobuf/generated_message_util.h
@@ -316,6 +316,13 @@
std::unique_ptr<storage_type[]> items_;
};
+// Single message link for implicit weak descriptor messages.
+// The runtime will register all the instances that are linked in.
+struct WeakDefaultWriter {
+ const Message** destination;
+ const Message* source;
+};
+
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index 1b8b329..91f770c 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -22,8 +22,10 @@
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
+#include "absl/types/optional.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
+#include "google/protobuf/dynamic_message.h"
#include "google/protobuf/generated_message_reflection.h"
#include "google/protobuf/generated_message_tctable_impl.h"
#include "google/protobuf/generated_message_util.h"
@@ -218,15 +220,21 @@
void RegisterFile(const google::protobuf::internal::DescriptorTable* table);
void RegisterType(const Descriptor* descriptor, const Message* prototype);
+ const Message* TryGetPrototype(const Descriptor* type);
+
// implements MessageFactory ---------------------------------------
const Message* GetPrototype(const Descriptor* type) override;
private:
- const Message* FindInTypeMap(const Descriptor* type)
+ GeneratedMessageFactory() {
+ dropped_defaults_factory_.SetDelegateToGeneratedFactory(true);
+ }
+
+ absl::optional<const Message*> FindInTypeMap(const Descriptor* type)
ABSL_SHARED_LOCKS_REQUIRED(mutex_)
{
auto it = type_map_.find(type);
- if (it == type_map_.end()) return nullptr;
+ if (it == type_map_.end()) return absl::nullopt;
return it->second;
}
@@ -270,6 +278,7 @@
absl::flat_hash_set<const google::protobuf::internal::DescriptorTable*,
DescriptorByNameHash, DescriptorByNameEq>
files_;
+ DynamicMessageFactory dropped_defaults_factory_;
absl::Mutex mutex_;
absl::flat_hash_map<const Descriptor*, const Message*> type_map_
@@ -307,10 +316,36 @@
const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) {
+ const Message* result = TryGetPrototype(type);
+ if (result == nullptr &&
+ type->file()->pool() == DescriptorPool::generated_pool()) {
+ // We registered this descriptor with a null pointer.
+ // In this case we need to create the prototype from the dynamic factory.
+ // We _must_ do this outside the lock because the dynamic factory will call
+ // back into the generated factory for cross linking.
+ result = dropped_defaults_factory_.GetPrototype(type);
+
+ {
+ absl::WriterMutexLock lock(&mutex_);
+ // And update the main map to make the next lookup faster.
+ // We don't need to recheck here. Even if someone raced us here the result
+ // is the same, so we can just write it.
+ type_map_[type] = result;
+ }
+ }
+
+ return result;
+}
+
+const Message* GeneratedMessageFactory::TryGetPrototype(
+ const Descriptor* type) {
+ absl::optional<const Message*> result;
{
absl::ReaderMutexLock lock(&mutex_);
- const Message* result = FindInTypeMap(type);
- if (result != nullptr) return result;
+ result = FindInTypeMap(type);
+ if (result.has_value() && *result != nullptr) {
+ return *result;
+ }
}
// If the type is not in the generated pool, then we can't possibly handle
@@ -327,27 +362,30 @@
return nullptr;
}
- absl::WriterMutexLock lock(&mutex_);
+ {
+ absl::WriterMutexLock lock(&mutex_);
- // Check if another thread preempted us.
- const Message* result = FindInTypeMap(type);
- if (result == nullptr) {
- // Nope. OK, register everything.
- internal::RegisterFileLevelMetadata(registration_data);
- // Should be here now.
+ // Check if another thread preempted us.
result = FindInTypeMap(type);
+ if (!result.has_value()) {
+ // Nope. OK, register everything.
+ internal::RegisterFileLevelMetadata(registration_data);
+ // Should be here now.
+ result = FindInTypeMap(type);
+ ABSL_DCHECK(result.has_value());
+ }
}
- if (result == nullptr) {
- ABSL_DLOG(FATAL) << "Type appears to be in generated pool but wasn't "
- << "registered: " << type->full_name();
- }
-
- return result;
+ return *result;
}
} // namespace
+const Message* MessageFactory::TryGetGeneratedPrototype(
+ const Descriptor* type) {
+ return GeneratedMessageFactory::singleton()->TryGetPrototype(type);
+}
+
MessageFactory* MessageFactory::generated_factory() {
return GeneratedMessageFactory::singleton();
}
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index c3b41a0..6f206a3 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -1347,6 +1347,10 @@
static void InternalRegisterGeneratedMessage(const Descriptor* descriptor,
const Message* prototype);
+
+ private:
+ friend class DynamicMessageFactory;
+ static const Message* TryGetGeneratedPrototype(const Descriptor* type);
};
#define DECLARE_GET_REPEATED_FIELD(TYPE) \
@@ -1389,6 +1393,7 @@
(void)unused;
#if PROTOBUF_RTTI
+ internal::StrongReference(T::default_instance());
return dynamic_cast<const T*>(from);
#else
bool ok = from != nullptr &&
@@ -1427,11 +1432,7 @@
// instance T and T is a type derived from base Message class.
template <typename T>
const T* DownCastToGenerated(const Message* from) {
- // Compile-time assert that T is a generated type that has a
- // default_instance() accessor, but avoid actually calling it.
- const T& (*get_default_instance)() = &T::default_instance;
- (void)get_default_instance;
-
+ internal::StrongReference(T::default_instance());
ABSL_DCHECK(DynamicCastToGenerated<T>(from) == from)
<< "Cannot downcast " << from->GetTypeName() << " to "
<< T::default_instance().GetTypeName();
diff --git a/src/google/protobuf/port.h b/src/google/protobuf/port.h
index 9aee882..da59316 100644
--- a/src/google/protobuf/port.h
+++ b/src/google/protobuf/port.h
@@ -39,6 +39,12 @@
namespace internal {
+template <typename T>
+void StrongPointer(T* var) {
+ auto volatile unused = var;
+ (void)&unused; // Use address to avoid an extra load of "unused".
+}
+
// See comments on `AllocateAtLeast` for information on size returning new.
struct SizedPtr {
void* p;
diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc
index dfd3f88..235644a 100644
--- a/src/google/protobuf/port_def.inc
+++ b/src/google/protobuf/port_def.inc
@@ -782,6 +782,15 @@
#define PROTOBUF_BUILTIN_CONSTANT_P(x) false
#endif
+// Determines the platforms where descriptor weak messages can be used.
+#ifdef PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED
+#error PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED was previously defined
+#endif
+#if defined(__GNUC__) && defined(__clang__) && !defined(__APPLE__) && \
+ !defined(_MSC_VER)
+#define PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED
+#endif
+
// TODO: Enable the feature by default and remove this flag.
#ifdef PROTOBUF_PREFETCH_PARSE_TABLE
diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc
index 277971f..70fca1c 100644
--- a/src/google/protobuf/port_undef.inc
+++ b/src/google/protobuf/port_undef.inc
@@ -78,6 +78,7 @@
#undef PROTOBUF_TSAN_WRITE
#undef PROTOBUF_USE_TABLE_PARSER_ON_REFLECTION
#undef PROTOBUF_BUILTIN_CONSTANT_P
+#undef PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED
#undef PROTOBUF_PREFETCH_PARSE_TABLE
#undef PROTOBUF_TC_PARAM_DECL
#undef PROTOBUF_DEBUG