Use Emit instead of format for extension code gen. PiperOrigin-RevId: 578983008
diff --git a/src/google/protobuf/compiler/cpp/extension.cc b/src/google/protobuf/compiler/cpp/extension.cc index fcb6f74..361d2cc 100644 --- a/src/google/protobuf/compiler/cpp/extension.cc +++ b/src/google/protobuf/compiler/cpp/extension.cc
@@ -11,9 +11,12 @@ #include "google/protobuf/compiler/cpp/extension.h" +#include <string> + #include "absl/strings/str_cat.h" #include "absl/strings/str_replace.h" #include "google/protobuf/compiler/cpp/helpers.h" +#include "google/protobuf/compiler/cpp/options.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/io/printer.h" @@ -77,97 +80,134 @@ variables_["scope"] = scope; variables_["scoped_name"] = ExtensionName(descriptor_); variables_["number"] = absl::StrCat(descriptor_->number()); - - bool add_verify_fn = - // 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_); - - variables_["verify_fn"] = - add_verify_fn - ? absl::StrCat("&", FieldMessageTypeName(descriptor_, options_), - "::InternalVerify") - : "nullptr"; } -ExtensionGenerator::~ExtensionGenerator() {} +ExtensionGenerator::~ExtensionGenerator() = default; bool ExtensionGenerator::IsScoped() const { return descriptor_->extension_scope() != nullptr; } -void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) const { - Formatter format(printer, variables_); +void ExtensionGenerator::GenerateDeclaration(io::Printer* p) const { + auto var = p->WithVars(variables_); + auto annotate = p->WithAnnotations({{"name", descriptor_}}); - // If this is a class member, it needs to be declared "static". Otherwise, - // it needs to be "extern". In the latter case, it also needs the DLL - // export/import specifier. - std::string qualifier; - if (!IsScoped()) { - qualifier = "extern"; - if (!options_.dllexport_decl.empty()) { - qualifier = absl::StrCat(options_.dllexport_decl, " ", qualifier); - } - } else { - qualifier = "static"; - } - - format( - "static const int $constant_name$ = $number$;\n" - "$1$ ::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n" - " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n" - " ${2$$name$$}$;\n", - qualifier, descriptor_); + p->Emit({{"qualifier", + // If this is a class member, it needs to be declared "static". + // Otherwise, it needs to be "extern". In the latter case, it + // also needs the DLL export/import specifier. + IsScoped() ? "static" + : options_.dllexport_decl.empty() + ? "extern" + : absl::StrCat(options_.dllexport_decl, " extern")}}, + R"cc( + static const int $constant_name$ = $number$; + $qualifier$ ::$proto_ns$::internal::ExtensionIdentifier< + $extendee$, ::$proto_ns$::internal::$type_traits$, $field_type$, + $packed$> + $name$; + )cc"); } -void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { - Formatter format(printer, variables_); - std::string default_str; - // If this is a class member, it needs to be declared in its class scope. - if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { - // We need to declare a global string which will contain the default value. - // We cannot declare it at class scope because that would require exposing - // it in the header which would be annoying for other reasons. So we - // replace :: with _ in the name and declare it as a global. - default_str = - absl::StrReplaceAll(variables_["scoped_name"], {{"::", "_"}}) + - "_default"; - format("const std::string $1$($2$);\n", default_str, - DefaultValue(options_, descriptor_)); - } else if (descriptor_->message_type()) { - // We have to initialize the default instance for extensions at registration - // time. - default_str = absl::StrCat(FieldMessageTypeName(descriptor_, options_), - "::default_instance()"); - } else { - default_str = DefaultValue(options_, descriptor_); - } +void ExtensionGenerator::GenerateDefinition(io::Printer* p) { + auto vars = p->WithVars(variables_); + auto generate_default_string = [&] { + if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { + // We need to declare a global string which will contain the default + // value. We cannot declare it at class scope because that would require + // exposing it in the header which would be annoying for other reasons. So + // we replace :: with _ in the name and declare it as a global. + return absl::StrReplaceAll(variables_["scoped_name"], {{"::", "_"}}) + + "_default"; + } 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()"); + } else { + return DefaultValue(options_, descriptor_); + } + }; - // Likewise, class members need to declare the field constant variable. - if (IsScoped()) { - format( - "#if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)\n" - "const int $scope$$constant_name$;\n" - "#endif\n"); - } + auto local_var = p->WithVars({ + {"default_str", generate_default_string()}, + {"default_val", DefaultValue(options_, descriptor_)}, + {"message_type", descriptor_->message_type() != nullptr + ? FieldMessageTypeName(descriptor_, options_) + : ""}, + }); + p->Emit( + { + {"declare_default_str", + [&] { + if (descriptor_->cpp_type() != FieldDescriptor::CPPTYPE_STRING) + return; - if (IsLazilyInitializedFile(descriptor_->file()->name())) { - format( - "PROTOBUF_CONSTINIT$ dllexport_decl$ " - "PROTOBUF_ATTRIBUTE_INIT_PRIORITY2\n" - "::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n" - " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$>\n" - " $scoped_name$($constant_name$);\n"); - } else { - format( - "$dllexport_decl $PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 " - "::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n" - " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$>\n" - " $scoped_name$($constant_name$, $1$, $verify_fn$);\n", - default_str); - } + // If this is a class member, it needs to be declared in its class + // scope. + p->Emit(R"cc( + const std::string $default_str$($default_val$); + )cc"); + }}, + {"declare_const_var", + [&] { + if (!IsScoped()) return; + // Likewise, class members need to declare the field constant + // variable. + p->Emit(R"cc( +#if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912) + const int $scope$$constant_name$; +#endif + )cc"); + }}, + {"define_extension_id", + [&] { + if (IsLazilyInitializedFile(descriptor_->file()->name())) { + p->Emit(R"cc( + PROTOBUF_CONSTINIT$ dllexport_decl$ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::$proto_ns$::internal:: + ExtensionIdentifier< + $extendee$, ::$proto_ns$::internal::$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 :: + $proto_ns$::internal::ExtensionIdentifier< + $extendee$, ::$proto_ns$::internal::$type_traits$, + $field_type$, $packed$> + $scoped_name$($constant_name$, $default_str$, + &$message_type$::InternalVerify); + )cc"); + } else { + p->Emit(R"cc( + $dllexport_decl $PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 :: + $proto_ns$::internal::ExtensionIdentifier< + $extendee$, ::$proto_ns$::internal::$type_traits$, + $field_type$, $packed$> + $scoped_name$($constant_name$, $default_str$, nullptr); + )cc"); + } + }}, + }, + R"cc( + $declare_default_str$; + $declare_const_var$; + $define_extension_id$; + )cc"); } } // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/extension.h b/src/google/protobuf/compiler/cpp/extension.h index 406bb63..aab3b64 100644 --- a/src/google/protobuf/compiler/cpp/extension.h +++ b/src/google/protobuf/compiler/cpp/extension.h
@@ -51,10 +51,10 @@ ~ExtensionGenerator(); // Header stuff. - void GenerateDeclaration(io::Printer* printer) const; + void GenerateDeclaration(io::Printer* p) const; // Source file stuff. - void GenerateDefinition(io::Printer* printer); + void GenerateDefinition(io::Printer* p); bool IsScoped() const;
diff --git a/src/google/protobuf/compiler/java/java_features.pb.cc b/src/google/protobuf/compiler/java/java_features.pb.cc index 3093752..4378405 100644 --- a/src/google/protobuf/compiler/java/java_features.pb.cc +++ b/src/google/protobuf/compiler/java/java_features.pb.cc
@@ -375,9 +375,11 @@ &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 ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::FeatureSet, - ::google::protobuf::internal::MessageTypeTraits< ::pb::JavaFeatures >, 11, false> - java(kJavaFieldNumber, ::pb::JavaFeatures::default_instance(), nullptr); +PROTOC_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 :: + google::protobuf::internal::ExtensionIdentifier< + ::google::protobuf::FeatureSet, ::google::protobuf::internal::MessageTypeTraits< ::pb::JavaFeatures >, + 11, false> + java(kJavaFieldNumber, ::pb::JavaFeatures::default_instance(), nullptr); // @@protoc_insertion_point(namespace_scope) } // namespace pb namespace google {
diff --git a/src/google/protobuf/compiler/java/java_features.pb.h b/src/google/protobuf/compiler/java/java_features.pb.h index 1a0c7bb..88584ab 100644 --- a/src/google/protobuf/compiler/java/java_features.pb.h +++ b/src/google/protobuf/compiler/java/java_features.pb.h
@@ -318,9 +318,10 @@ static const int kJavaFieldNumber = 1001; -PROTOC_EXPORT extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::FeatureSet, - ::google::protobuf::internal::MessageTypeTraits< ::pb::JavaFeatures >, 11, false > - java; +PROTOC_EXPORT extern ::google::protobuf::internal::ExtensionIdentifier< + ::google::protobuf::FeatureSet, ::google::protobuf::internal::MessageTypeTraits< ::pb::JavaFeatures >, 11, + false> + java; // ===================================================================
diff --git a/src/google/protobuf/cpp_features.pb.cc b/src/google/protobuf/cpp_features.pb.cc index b7eee1a..6e5538d 100644 --- a/src/google/protobuf/cpp_features.pb.cc +++ b/src/google/protobuf/cpp_features.pb.cc
@@ -298,10 +298,12 @@ &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 -::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::FeatureSet, - ::google::protobuf::internal::MessageTypeTraits< ::pb::CppFeatures >, 11, false> - cpp(kCppFieldNumber); +PROTOBUF_CONSTINIT PROTOBUF_EXPORT + PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::google::protobuf::internal:: + ExtensionIdentifier< + ::google::protobuf::FeatureSet, ::google::protobuf::internal::MessageTypeTraits< ::pb::CppFeatures >, + 11, false> + cpp(kCppFieldNumber); // @@protoc_insertion_point(namespace_scope) } // namespace pb namespace google {
diff --git a/src/google/protobuf/cpp_features.pb.h b/src/google/protobuf/cpp_features.pb.h index 3b47043..6e2c967 100644 --- a/src/google/protobuf/cpp_features.pb.h +++ b/src/google/protobuf/cpp_features.pb.h
@@ -253,9 +253,10 @@ static const int kCppFieldNumber = 1000; -PROTOBUF_EXPORT extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::FeatureSet, - ::google::protobuf::internal::MessageTypeTraits< ::pb::CppFeatures >, 11, false > - cpp; +PROTOBUF_EXPORT extern ::google::protobuf::internal::ExtensionIdentifier< + ::google::protobuf::FeatureSet, ::google::protobuf::internal::MessageTypeTraits< ::pb::CppFeatures >, 11, + false> + cpp; // ===================================================================