[Upb C++] Split name-related functions from gen_utils.{h,cc} into names.{h,cc}. Also create a separate build target for output.{h,cc} (though it's kept private, since we prefer protobuf/io/printer.h for newer code).
PiperOrigin-RevId: 535333251
diff --git a/protos_generator/BUILD b/protos_generator/BUILD
index 2414ff5..acc0c1a 100644
--- a/protos_generator/BUILD
+++ b/protos_generator/BUILD
@@ -42,7 +42,10 @@
copts = UPB_DEFAULT_CPPOPTS,
visibility = ["//visibility:public"],
deps = [
+ ":gen_utils",
":generator",
+ ":names",
+ ":output",
"//upbc:file_layout",
"@com_google_protobuf//:protobuf",
"@com_google_protobuf//src/google/protobuf/compiler:code_generator",
@@ -57,8 +60,6 @@
"gen_extensions.cc",
"gen_messages.cc",
"gen_repeated_fields.cc",
- "gen_utils.cc",
- "output.cc",
],
hdrs = [
"gen_accessors.h",
@@ -66,22 +67,53 @@
"gen_extensions.h",
"gen_messages.h",
"gen_repeated_fields.h",
- "gen_utils.h",
- "output.h",
],
visibility = ["//visibility:private"],
deps = [
- "//:message_copy",
+ ":gen_utils",
+ ":names",
+ ":output",
+ "@com_google_absl//absl/container:flat_hash_set",
+ "@com_google_absl//absl/strings",
"//upbc:common",
"//upbc:file_layout",
"//upbc:keywords",
"//upbc:names",
- "@com_google_absl//absl/container:flat_hash_map",
- "@com_google_absl//absl/container:flat_hash_set",
- "@com_google_absl//absl/log:absl_check",
+ "@com_google_protobuf//:protobuf",
+ ],
+)
+
+cc_library(
+ name = "output",
+ srcs = ["output.cc"],
+ hdrs = ["output.h"],
+ visibility = ["//visibility:private"],
+ deps = [
"@com_google_absl//absl/log:absl_log",
"@com_google_absl//absl/strings",
"@com_google_protobuf//:protobuf",
+ ],
+)
+
+cc_library(
+ name = "gen_utils",
+ srcs = ["gen_utils.cc"],
+ hdrs = ["gen_utils.h"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "@com_google_absl//absl/strings",
+ "@com_google_protobuf//:protobuf",
"@com_google_protobuf//src/google/protobuf/compiler:code_generator",
],
)
+
+cc_library(
+ name = "names",
+ srcs = ["names.cc"],
+ hdrs = ["names.h"],
+ visibility = ["//visibility:private"],
+ deps = [
+ ":output",
+ "//upbc:keywords",
+ ],
+)
diff --git a/protos_generator/gen_accessors.cc b/protos_generator/gen_accessors.cc
index bd3898b..f7324e8 100644
--- a/protos_generator/gen_accessors.cc
+++ b/protos_generator/gen_accessors.cc
@@ -34,6 +34,7 @@
#include "google/protobuf/descriptor.h"
#include "protos_generator/gen_repeated_fields.h"
#include "protos_generator/gen_utils.h"
+#include "protos_generator/names.h"
#include "protos_generator/output.h"
#include "upbc/common.h"
#include "upbc/keywords.h"
diff --git a/protos_generator/gen_enums.cc b/protos_generator/gen_enums.cc
index e1ad32b..6e2aa39 100644
--- a/protos_generator/gen_enums.cc
+++ b/protos_generator/gen_enums.cc
@@ -33,6 +33,7 @@
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/descriptor.h"
#include "protos_generator/gen_utils.h"
+#include "protos_generator/names.h"
namespace protos_generator {
diff --git a/protos_generator/gen_extensions.cc b/protos_generator/gen_extensions.cc
index 167fa2f..979284d 100644
--- a/protos_generator/gen_extensions.cc
+++ b/protos_generator/gen_extensions.cc
@@ -27,6 +27,7 @@
#include "absl/strings/str_cat.h"
#include "protos_generator/gen_utils.h"
+#include "protos_generator/names.h"
namespace protos_generator {
diff --git a/protos_generator/gen_messages.cc b/protos_generator/gen_messages.cc
index 7715193..8d81fbd 100644
--- a/protos_generator/gen_messages.cc
+++ b/protos_generator/gen_messages.cc
@@ -36,6 +36,7 @@
#include "protos_generator/gen_enums.h"
#include "protos_generator/gen_extensions.h"
#include "protos_generator/gen_utils.h"
+#include "protos_generator/names.h"
#include "protos_generator/output.h"
#include "upbc/common.h"
#include "upbc/file_layout.h"
diff --git a/protos_generator/gen_repeated_fields.cc b/protos_generator/gen_repeated_fields.cc
index 1454c10..2564334 100644
--- a/protos_generator/gen_repeated_fields.cc
+++ b/protos_generator/gen_repeated_fields.cc
@@ -35,6 +35,7 @@
#include "protos_generator/gen_enums.h"
#include "protos_generator/gen_extensions.h"
#include "protos_generator/gen_utils.h"
+#include "protos_generator/names.h"
#include "protos_generator/output.h"
#include "upbc/common.h"
#include "upbc/file_layout.h"
diff --git a/protos_generator/gen_utils.cc b/protos_generator/gen_utils.cc
index 53630fd..b4ecf04 100644
--- a/protos_generator/gen_utils.cc
+++ b/protos_generator/gen_utils.cc
@@ -29,175 +29,14 @@
#include <algorithm>
#include <string>
+#include <vector>
-#include "absl/log/absl_check.h"
-#include "absl/strings/str_cat.h"
-// begin:google_only
-// #include "absl/strings/str_replace.h"
-// end:google_only
-#include "absl/strings/str_split.h"
-#include "upbc/keywords.h"
+#include "absl/strings/ascii.h"
namespace protos_generator {
namespace protobuf = ::google::protobuf;
-std::string DotsToColons(const std::string& name) {
- return absl::StrReplaceAll(name, {{".", "::"}});
-}
-
-std::string Namespace(const std::string& package) {
- if (package.empty()) return "";
- return "::" + DotsToColons(package);
-}
-
-// Return the qualified C++ name for a file level symbol.
-std::string QualifiedFileLevelSymbol(const protobuf::FileDescriptor* file,
- const std::string& name) {
- if (file->package().empty()) {
- return absl::StrCat("::", name);
- }
- // Append ::protos postfix to package name.
- return absl::StrCat(Namespace(file->package()), "::protos::", name);
-}
-
-std::string ClassName(const protobuf::Descriptor* descriptor) {
- const protobuf::Descriptor* parent = descriptor->containing_type();
- std::string res;
- // Classes in global namespace without package names are prefixed
- // by protos_ to avoid collision with C compiler structs defined in
- // proto.upb.h.
- if ((parent && parent->file()->package().empty()) ||
- descriptor->file()->package().empty()) {
- res = std::string(kNoPackageNamePrefix);
- }
- if (parent) res += ClassName(parent) + "_";
- absl::StrAppend(&res, descriptor->name());
- return ::upbc::ResolveKeywordConflict(res);
-}
-
-std::string QualifiedClassName(const protobuf::Descriptor* descriptor) {
- return QualifiedFileLevelSymbol(descriptor->file(), ClassName(descriptor));
-}
-
-std::string QualifiedInternalClassName(const protobuf::Descriptor* descriptor) {
- return QualifiedFileLevelSymbol(
- descriptor->file(), absl::StrCat("internal::", ClassName(descriptor)));
-}
-
-std::string CppSourceFilename(const google::protobuf::FileDescriptor* file) {
- return StripExtension(file->name()) + ".upb.proto.cc";
-}
-
-std::string UpbCFilename(const google::protobuf::FileDescriptor* file) {
- return StripExtension(file->name()) + ".upb.h";
-}
-
-std::string ForwardingHeaderFilename(const google::protobuf::FileDescriptor* file) {
- return StripExtension(file->name()) + ".upb.fwd.h";
-}
-
-std::string CppHeaderFilename(const google::protobuf::FileDescriptor* file) {
- return StripExtension(file->name()) + ".upb.proto.h";
-}
-
-std::string NamespaceFromPackageName(absl::string_view package_name) {
- return absl::StrCat(absl::StrReplaceAll(package_name, {{".", "::"}}),
- "::protos");
-}
-
-void WriteStartNamespace(const protobuf::FileDescriptor* file, Output& output) {
- // Skip namespace generation if package name is not specified.
- if (file->package().empty()) {
- return;
- }
-
- output("namespace $0 {\n\n", NamespaceFromPackageName(file->package()));
-}
-
-void WriteEndNamespace(const protobuf::FileDescriptor* file, Output& output) {
- if (file->package().empty()) {
- return;
- }
- output("} // namespace $0\n\n", NamespaceFromPackageName(file->package()));
-}
-
-std::string CppTypeInternal(const protobuf::FieldDescriptor* field,
- bool is_const, bool is_type_parameter) {
- std::string maybe_const = is_const ? "const " : "";
- switch (field->cpp_type()) {
- case protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
- if (is_type_parameter) {
- return absl::StrCat(maybe_const,
- QualifiedClassName(field->message_type()));
- } else {
- return absl::StrCat(maybe_const,
- QualifiedClassName(field->message_type()), "*");
- }
- }
- case protobuf::FieldDescriptor::CPPTYPE_BOOL:
- return "bool";
- case protobuf::FieldDescriptor::CPPTYPE_FLOAT:
- return "float";
- case protobuf::FieldDescriptor::CPPTYPE_INT32:
- case protobuf::FieldDescriptor::CPPTYPE_ENUM:
- return "int32_t";
- case protobuf::FieldDescriptor::CPPTYPE_UINT32:
- return "uint32_t";
- case protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
- return "double";
- case protobuf::FieldDescriptor::CPPTYPE_INT64:
- return "int64_t";
- case protobuf::FieldDescriptor::CPPTYPE_UINT64:
- return "uint64_t";
- case protobuf::FieldDescriptor::CPPTYPE_STRING:
- return "absl::string_view";
- default:
- ABSL_LOG(FATAL) << "Unexpected type: " << field->cpp_type();
- }
-}
-
-std::string CppConstType(const protobuf::FieldDescriptor* field) {
- return CppTypeInternal(field, /* is_const= */ true,
- /* is_type_parameter= */ false);
-}
-
-std::string CppTypeParameterName(const protobuf::FieldDescriptor* field) {
- return CppTypeInternal(field, /* is_const= */ false,
- /* is_type_parameter= */ true);
-}
-
-std::string MessageBaseType(const protobuf::FieldDescriptor* field,
- bool is_const) {
- ABSL_DCHECK(field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE);
- std::string maybe_const = is_const ? "const " : "";
- return maybe_const + QualifiedClassName(field->message_type());
-}
-
-std::string MessagePtrConstType(const protobuf::FieldDescriptor* field,
- bool is_const) {
- ABSL_DCHECK(field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE);
- std::string maybe_const = is_const ? "const " : "";
- return "::protos::Ptr<" + maybe_const +
- QualifiedClassName(field->message_type()) + ">";
-}
-
-std::string MessageCProxyType(const protobuf::FieldDescriptor* field,
- bool is_const) {
- ABSL_DCHECK(field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE);
- std::string maybe_const = is_const ? "const " : "";
- return maybe_const + QualifiedInternalClassName(field->message_type()) +
- "CProxy";
-}
-
-std::string MessageProxyType(const protobuf::FieldDescriptor* field,
- bool is_const) {
- ABSL_DCHECK(field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE);
- std::string maybe_const = is_const ? "const " : "";
- return maybe_const + QualifiedInternalClassName(field->message_type()) +
- "Proxy";
-}
-
void AddEnums(const protobuf::Descriptor* message,
std::vector<const protobuf::EnumDescriptor*>* enums) {
enums->reserve(enums->size() + message->enum_type_count());
@@ -252,13 +91,19 @@
std::vector<const protobuf::FieldDescriptor*> SortedExtensions(
const protobuf::FileDescriptor* file) {
+ const int extension_count = file->extension_count();
+ const int message_type_count = file->message_type_count();
+
std::vector<const protobuf::FieldDescriptor*> ret;
- for (int i = 0; i < file->extension_count(); i++) {
+ ret.reserve(extension_count + message_type_count);
+
+ for (int i = 0; i < extension_count; i++) {
ret.push_back(file->extension(i));
}
- for (int i = 0; i < file->message_type_count(); i++) {
+ for (int i = 0; i < message_type_count; i++) {
AddExtensionsFromMessage(file->message_type(i), &ret);
}
+
return ret;
}
diff --git a/protos_generator/gen_utils.h b/protos_generator/gen_utils.h
index 394c244..593c06a 100644
--- a/protos_generator/gen_utils.h
+++ b/protos_generator/gen_utils.h
@@ -28,16 +28,12 @@
#ifndef UPB_PROTOS_GENERATOR_GEN_UTILS_H_
#define UPB_PROTOS_GENERATOR_GEN_UTILS_H_
+#include <string>
#include <vector>
#include "google/protobuf/descriptor.pb.h"
-#include "absl/container/flat_hash_map.h"
-#include "absl/strings/string_view.h"
#include "google/protobuf/compiler/code_generator.h"
-#include "google/protobuf/compiler/plugin.h"
#include "google/protobuf/descriptor.h"
-#include "google/protobuf/wire_format.h"
-#include "protos_generator/output.h"
namespace protos_generator {
@@ -50,35 +46,9 @@
kMessageAccess,
};
-std::string ClassName(const protobuf::Descriptor* descriptor);
-std::string QualifiedClassName(const protobuf::Descriptor* descriptor);
-std::string QualifiedInternalClassName(const protobuf::Descriptor* descriptor);
-
inline bool IsMapEntryMessage(const protobuf::Descriptor* descriptor) {
return descriptor->options().map_entry();
}
-std::string CppSourceFilename(const google::protobuf::FileDescriptor* file);
-std::string ForwardingHeaderFilename(const google::protobuf::FileDescriptor* file);
-std::string UpbCFilename(const google::protobuf::FileDescriptor* file);
-std::string CppHeaderFilename(const google::protobuf::FileDescriptor* file);
-
-void WriteStartNamespace(const protobuf::FileDescriptor* file, Output& output);
-void WriteEndNamespace(const protobuf::FileDescriptor* file, Output& output);
-
-std::string CppConstType(const protobuf::FieldDescriptor* field);
-std::string CppTypeParameterName(const protobuf::FieldDescriptor* field);
-
-std::string MessageBaseType(const protobuf::FieldDescriptor* field,
- bool is_const);
-// Generate protos::Ptr<const Model> to be used in accessors as public
-// signatures.
-std::string MessagePtrConstType(const protobuf::FieldDescriptor* field,
- bool is_const);
-std::string MessageCProxyType(const protobuf::FieldDescriptor* field,
- bool is_const);
-std::string MessageProxyType(const protobuf::FieldDescriptor* field,
- bool is_const);
-
std::vector<const protobuf::EnumDescriptor*> SortedEnums(
const protobuf::FileDescriptor* file);
std::vector<const protobuf::Descriptor*> SortedMessages(
@@ -88,8 +58,6 @@
std::vector<const protobuf::FieldDescriptor*> FieldNumberOrder(
const protobuf::Descriptor* message);
-inline constexpr absl::string_view kNoPackageNamePrefix = "protos_";
-
std::string ToCamelCase(const std::string& input, bool lower_first);
} // namespace protos_generator
diff --git a/protos_generator/names.cc b/protos_generator/names.cc
new file mode 100644
index 0000000..0149071
--- /dev/null
+++ b/protos_generator/names.cc
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2009-2021, Google LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Google LLC nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "protos_generator/names.h"
+
+#include <string>
+
+#include "upbc/keywords.h"
+
+namespace protos_generator {
+
+namespace protobuf = ::google::protobuf;
+
+namespace {
+
+std::string NamespaceFromPackageName(absl::string_view package_name) {
+ return absl::StrCat(absl::StrReplaceAll(package_name, {{".", "::"}}),
+ "::protos");
+}
+
+std::string DotsToColons(const std::string& name) {
+ return absl::StrReplaceAll(name, {{".", "::"}});
+}
+
+std::string Namespace(const std::string& package) {
+ if (package.empty()) return "";
+ return "::" + DotsToColons(package);
+}
+
+// Return the qualified C++ name for a file level symbol.
+std::string QualifiedFileLevelSymbol(const protobuf::FileDescriptor* file,
+ const std::string& name) {
+ if (file->package().empty()) {
+ return absl::StrCat("::", name);
+ }
+ // Append ::protos postfix to package name.
+ return absl::StrCat(Namespace(file->package()), "::protos::", name);
+}
+
+std::string CppTypeInternal(const protobuf::FieldDescriptor* field,
+ bool is_const, bool is_type_parameter) {
+ std::string maybe_const = is_const ? "const " : "";
+ switch (field->cpp_type()) {
+ case protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
+ if (is_type_parameter) {
+ return absl::StrCat(maybe_const,
+ QualifiedClassName(field->message_type()));
+ } else {
+ return absl::StrCat(maybe_const,
+ QualifiedClassName(field->message_type()), "*");
+ }
+ }
+ case protobuf::FieldDescriptor::CPPTYPE_BOOL:
+ return "bool";
+ case protobuf::FieldDescriptor::CPPTYPE_FLOAT:
+ return "float";
+ case protobuf::FieldDescriptor::CPPTYPE_INT32:
+ case protobuf::FieldDescriptor::CPPTYPE_ENUM:
+ return "int32_t";
+ case protobuf::FieldDescriptor::CPPTYPE_UINT32:
+ return "uint32_t";
+ case protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
+ return "double";
+ case protobuf::FieldDescriptor::CPPTYPE_INT64:
+ return "int64_t";
+ case protobuf::FieldDescriptor::CPPTYPE_UINT64:
+ return "uint64_t";
+ case protobuf::FieldDescriptor::CPPTYPE_STRING:
+ return "absl::string_view";
+ default:
+ ABSL_LOG(FATAL) << "Unexpected type: " << field->cpp_type();
+ }
+}
+
+} // namespace
+
+std::string ClassName(const protobuf::Descriptor* descriptor) {
+ const protobuf::Descriptor* parent = descriptor->containing_type();
+ std::string res;
+ // Classes in global namespace without package names are prefixed
+ // by protos_ to avoid collision with C compiler structs defined in
+ // proto.upb.h.
+ if ((parent && parent->file()->package().empty()) ||
+ descriptor->file()->package().empty()) {
+ res = std::string(kNoPackageNamePrefix);
+ }
+ if (parent) res += ClassName(parent) + "_";
+ absl::StrAppend(&res, descriptor->name());
+ return ::upbc::ResolveKeywordConflict(res);
+}
+
+std::string QualifiedClassName(const protobuf::Descriptor* descriptor) {
+ return QualifiedFileLevelSymbol(descriptor->file(), ClassName(descriptor));
+}
+
+std::string QualifiedInternalClassName(const protobuf::Descriptor* descriptor) {
+ return QualifiedFileLevelSymbol(
+ descriptor->file(), absl::StrCat("internal::", ClassName(descriptor)));
+}
+
+std::string CppSourceFilename(const google::protobuf::FileDescriptor* file) {
+ return StripExtension(file->name()) + ".upb.proto.cc";
+}
+
+std::string ForwardingHeaderFilename(const google::protobuf::FileDescriptor* file) {
+ return StripExtension(file->name()) + ".upb.fwd.h";
+}
+
+std::string UpbCFilename(const google::protobuf::FileDescriptor* file) {
+ return StripExtension(file->name()) + ".upb.h";
+}
+
+std::string CppHeaderFilename(const google::protobuf::FileDescriptor* file) {
+ return StripExtension(file->name()) + ".upb.proto.h";
+}
+
+void WriteStartNamespace(const protobuf::FileDescriptor* file, Output& output) {
+ // Skip namespace generation if package name is not specified.
+ if (file->package().empty()) {
+ return;
+ }
+
+ output("namespace $0 {\n\n", NamespaceFromPackageName(file->package()));
+}
+
+void WriteEndNamespace(const protobuf::FileDescriptor* file, Output& output) {
+ if (file->package().empty()) {
+ return;
+ }
+ output("} // namespace $0\n\n", NamespaceFromPackageName(file->package()));
+}
+
+std::string CppConstType(const protobuf::FieldDescriptor* field) {
+ return CppTypeInternal(field, /* is_const= */ true,
+ /* is_type_parameter= */ false);
+}
+
+std::string CppTypeParameterName(const protobuf::FieldDescriptor* field) {
+ return CppTypeInternal(field, /* is_const= */ false,
+ /* is_type_parameter= */ true);
+}
+
+std::string MessageBaseType(const protobuf::FieldDescriptor* field,
+ bool is_const) {
+ ABSL_DCHECK(field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE);
+ std::string maybe_const = is_const ? "const " : "";
+ return maybe_const + QualifiedClassName(field->message_type());
+}
+
+std::string MessagePtrConstType(const protobuf::FieldDescriptor* field,
+ bool is_const) {
+ ABSL_DCHECK(field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE);
+ std::string maybe_const = is_const ? "const " : "";
+ return "::protos::Ptr<" + maybe_const +
+ QualifiedClassName(field->message_type()) + ">";
+}
+
+std::string MessageCProxyType(const protobuf::FieldDescriptor* field,
+ bool is_const) {
+ ABSL_DCHECK(field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE);
+ std::string maybe_const = is_const ? "const " : "";
+ return maybe_const + QualifiedInternalClassName(field->message_type()) +
+ "CProxy";
+}
+
+std::string MessageProxyType(const protobuf::FieldDescriptor* field,
+ bool is_const) {
+ ABSL_DCHECK(field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE);
+ std::string maybe_const = is_const ? "const " : "";
+ return maybe_const + QualifiedInternalClassName(field->message_type()) +
+ "Proxy";
+}
+
+} // namespace protos_generator
diff --git a/protos_generator/names.h b/protos_generator/names.h
new file mode 100644
index 0000000..afc0419
--- /dev/null
+++ b/protos_generator/names.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009-2021, Google LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Google LLC nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UPB_PROTOS_GENERATOR_NAMES_H_
+#define UPB_PROTOS_GENERATOR_NAMES_H_
+
+#include <string>
+
+#include "google/protobuf/descriptor.pb.h"
+#include "protos_generator/output.h"
+
+namespace protos_generator {
+
+namespace protobuf = ::google::protobuf;
+
+inline constexpr absl::string_view kNoPackageNamePrefix = "protos_";
+
+std::string ClassName(const protobuf::Descriptor* descriptor);
+std::string QualifiedClassName(const protobuf::Descriptor* descriptor);
+std::string QualifiedInternalClassName(const protobuf::Descriptor* descriptor);
+
+std::string CppSourceFilename(const google::protobuf::FileDescriptor* file);
+std::string ForwardingHeaderFilename(const google::protobuf::FileDescriptor* file);
+std::string UpbCFilename(const google::protobuf::FileDescriptor* file);
+std::string CppHeaderFilename(const google::protobuf::FileDescriptor* file);
+
+void WriteStartNamespace(const protobuf::FileDescriptor* file, Output& output);
+void WriteEndNamespace(const protobuf::FileDescriptor* file, Output& output);
+
+std::string CppConstType(const protobuf::FieldDescriptor* field);
+std::string CppTypeParameterName(const protobuf::FieldDescriptor* field);
+
+std::string MessageBaseType(const protobuf::FieldDescriptor* field,
+ bool is_const);
+// Generate protos::Ptr<const Model> to be used in accessors as public
+// signatures.
+std::string MessagePtrConstType(const protobuf::FieldDescriptor* field,
+ bool is_const);
+std::string MessageCProxyType(const protobuf::FieldDescriptor* field,
+ bool is_const);
+std::string MessageProxyType(const protobuf::FieldDescriptor* field,
+ bool is_const);
+
+} // namespace protos_generator
+
+#endif // UPB_PROTOS_GENERATOR_NAMES_H_
diff --git a/protos_generator/output.cc b/protos_generator/output.cc
index e5a9b79..255f631 100644
--- a/protos_generator/output.cc
+++ b/protos_generator/output.cc
@@ -25,6 +25,8 @@
#include "protos_generator/output.h"
+#include <string>
+
#include "absl/strings/str_replace.h"
namespace protos_generator {
diff --git a/protos_generator/protoc-gen-upb-protos.cc b/protos_generator/protoc-gen-upb-protos.cc
index 462898b..bc39d3e 100644
--- a/protos_generator/protoc-gen-upb-protos.cc
+++ b/protos_generator/protoc-gen-upb-protos.cc
@@ -33,6 +33,7 @@
#include "protos_generator/gen_extensions.h"
#include "protos_generator/gen_messages.h"
#include "protos_generator/gen_utils.h"
+#include "protos_generator/names.h"
#include "protos_generator/output.h"
#include "upbc/file_layout.h"