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;
 
 // ===================================================================