mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
Extract Python naming helper functions into a separate names library.
PiperOrigin-RevId: 961053716
This commit is contained in:
parent
620c9cf483
commit
b2e184385f
10 changed files with 130 additions and 54 deletions
|
|
@ -35,6 +35,7 @@ google/protobuf/compiler/php/names.h
|
|||
google/protobuf/compiler/plugin.h
|
||||
google/protobuf/compiler/plugin.pb.h
|
||||
google/protobuf/compiler/plugin.proto
|
||||
google/protobuf/compiler/python/names.h
|
||||
google/protobuf/compiler/retention.h
|
||||
google/protobuf/compiler/scc.h
|
||||
google/protobuf/compiler/subprocess.h
|
||||
|
|
|
|||
|
|
@ -222,6 +222,7 @@ cc_dist_library(
|
|||
"//src/google/protobuf/compiler/java:names",
|
||||
"//src/google/protobuf/compiler/objectivec:names",
|
||||
"//src/google/protobuf/compiler/php:names",
|
||||
"//src/google/protobuf/compiler/python:names",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,22 @@ cc_binary(
|
|||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "names",
|
||||
srcs = ["names.cc"],
|
||||
hdrs = ["names.h"],
|
||||
copts = COPTS,
|
||||
strip_include_prefix = "/src",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//src/google/protobuf",
|
||||
"//src/google/protobuf:port",
|
||||
"//src/google/protobuf/compiler:code_generator",
|
||||
"@abseil-cpp//absl/log:absl_check",
|
||||
"@abseil-cpp//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "python",
|
||||
srcs = [
|
||||
|
|
@ -47,6 +63,7 @@ cc_library(
|
|||
"@com_github_grpc_grpc//tools/distrib/python/grpcio_tools:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
":names",
|
||||
"//src/google/protobuf",
|
||||
"//src/google/protobuf:port",
|
||||
"//src/google/protobuf/compiler:code_generator",
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "absl/strings/substitute.h"
|
||||
#include "google/protobuf/compiler/code_generator.h"
|
||||
#include "google/protobuf/compiler/python/helpers.h"
|
||||
#include "google/protobuf/compiler/python/names.h"
|
||||
#include "google/protobuf/compiler/python/pyi_generator.h"
|
||||
#include "google/protobuf/compiler/retention.h"
|
||||
#include "google/protobuf/compiler/versions.h"
|
||||
|
|
@ -62,19 +63,6 @@ namespace compiler {
|
|||
namespace python {
|
||||
|
||||
namespace {
|
||||
// Returns the alias we assign to the module of the given .proto filename
|
||||
// when importing. See testPackageInitializationImport in
|
||||
// third_party/py/google/protobuf/internal/reflection_test.py
|
||||
// to see why we need the alias.
|
||||
std::string ModuleAlias(absl::string_view filename) {
|
||||
std::string module_name = ModuleName(filename);
|
||||
// We can't have dots in the module name, so we replace each with _dot_.
|
||||
// But that could lead to a collision between a.b and a_dot_b, so we also
|
||||
// duplicate each underscore.
|
||||
absl::StrReplaceAll({{"_", "__"}}, &module_name);
|
||||
absl::StrReplaceAll({{".", "_dot_"}}, &module_name);
|
||||
return module_name;
|
||||
}
|
||||
|
||||
// Name of the class attribute where we store the Python
|
||||
// descriptor.Descriptor instance for the generated class.
|
||||
|
|
@ -311,7 +299,7 @@ bool Generator::Generate(const FileDescriptor* file,
|
|||
if (GeneratingDescriptorProto()) {
|
||||
printer_->Outdent();
|
||||
}
|
||||
std::string module_name = ModuleName(file->name());
|
||||
std::string module_name = ModuleName(file);
|
||||
if (!opensource_runtime_) {
|
||||
module_name =
|
||||
std::string(absl::StripPrefix(module_name, kThirdPartyPrefix));
|
||||
|
|
@ -396,8 +384,8 @@ void Generator::PrintTopBoilerplate() const {
|
|||
printer_->Print("\n\n");
|
||||
}
|
||||
|
||||
std::string Generator::ImportModuleName(absl::string_view filename) const {
|
||||
std::string module_name = ModuleName(filename);
|
||||
std::string Generator::ImportModuleName(const FileDescriptor* file) const {
|
||||
std::string module_name = ModuleName(file);
|
||||
if (!opensource_runtime_) {
|
||||
module_name =
|
||||
std::string(absl::StripPrefix(module_name, kThirdPartyPrefix));
|
||||
|
|
@ -409,10 +397,8 @@ std::string Generator::ImportModuleName(absl::string_view filename) const {
|
|||
void Generator::PrintImports() const {
|
||||
bool has_importlib = false;
|
||||
for (int i = 0; i < file_->dependency_count(); ++i) {
|
||||
absl::string_view filename = file_->dependency(i)->name();
|
||||
|
||||
std::string module_name = ImportModuleName(filename);
|
||||
std::string module_alias = ModuleAlias(filename);
|
||||
std::string module_name = ImportModuleName(file_->dependency(i));
|
||||
std::string module_alias = ModuleAlias(file_->dependency(i));
|
||||
if (ContainsPythonKeyword(module_name)) {
|
||||
// If the module path contains a Python keyword, we have to quote the
|
||||
// module name and import it using importlib. Otherwise the usual kind of
|
||||
|
|
@ -446,8 +432,7 @@ void Generator::PrintImports() const {
|
|||
|
||||
// Print public imports.
|
||||
for (int i = 0; i < file_->public_dependency_count(); ++i) {
|
||||
std::string module_name =
|
||||
ImportModuleName(file_->public_dependency(i)->name());
|
||||
std::string module_name = ImportModuleName(file_->public_dependency(i));
|
||||
printer_->Print("from $module$ import *\n", "module", module_name);
|
||||
}
|
||||
printer_->Print("\n");
|
||||
|
|
@ -601,7 +586,7 @@ void Generator::PrintFileDescriptor() const {
|
|||
if (file_->dependency_count() != 0) {
|
||||
printer_->Print(",\ndependencies=[");
|
||||
for (int i = 0; i < file_->dependency_count(); ++i) {
|
||||
std::string module_alias = ModuleAlias(file_->dependency(i)->name());
|
||||
std::string module_alias = ModuleAlias(file_->dependency(i));
|
||||
printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
|
||||
module_alias);
|
||||
}
|
||||
|
|
@ -610,8 +595,7 @@ void Generator::PrintFileDescriptor() const {
|
|||
if (file_->public_dependency_count() > 0) {
|
||||
printer_->Print(",\npublic_dependencies=[");
|
||||
for (int i = 0; i < file_->public_dependency_count(); ++i) {
|
||||
std::string module_alias =
|
||||
ModuleAlias(file_->public_dependency(i)->name());
|
||||
std::string module_alias = ModuleAlias(file_->public_dependency(i));
|
||||
printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
|
||||
module_alias);
|
||||
}
|
||||
|
|
@ -741,7 +725,7 @@ void Generator::PrintDescriptorKeyAndModuleName(
|
|||
std::string name = ModuleLevelServiceDescriptorName(descriptor);
|
||||
printer_->Print("$descriptor_key$ = $descriptor_name$,\n", "descriptor_key",
|
||||
kDescriptorKey, "descriptor_name", name);
|
||||
std::string module_name = ModuleName(file_->name());
|
||||
std::string module_name = ModuleName(file_);
|
||||
if (!opensource_runtime_) {
|
||||
module_name =
|
||||
std::string(absl::StripPrefix(module_name, kThirdPartyPrefix));
|
||||
|
|
@ -937,7 +921,7 @@ void Generator::PrintMessage(const Descriptor& message_descriptor,
|
|||
m["descriptor_key"] = kDescriptorKey;
|
||||
m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
|
||||
printer_->Print(m, "'$descriptor_key$' : $descriptor_name$,\n");
|
||||
std::string module_name = ModuleName(file_->name());
|
||||
std::string module_name = ModuleName(file_);
|
||||
if (!opensource_runtime_) {
|
||||
module_name =
|
||||
std::string(absl::StripPrefix(module_name, kThirdPartyPrefix));
|
||||
|
|
@ -1275,7 +1259,7 @@ std::string Generator::ModuleLevelDescriptorName(
|
|||
// We now have the name relative to its own module. Also qualify with
|
||||
// the module name iff this descriptor is from a different .proto file.
|
||||
if (descriptor.file() != file_) {
|
||||
name = absl::StrCat(ModuleAlias(descriptor.file()->name()), ".", name);
|
||||
name = absl::StrCat(ModuleAlias(descriptor.file()), ".", name);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
|
@ -1288,7 +1272,7 @@ std::string Generator::ModuleLevelMessageName(
|
|||
const Descriptor& descriptor) const {
|
||||
std::string name = NamePrefixedWithNestedTypes(descriptor, ".");
|
||||
if (descriptor.file() != file_) {
|
||||
name = absl::StrCat(ModuleAlias(descriptor.file()->name()), ".", name);
|
||||
name = absl::StrCat(ModuleAlias(descriptor.file()), ".", name);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
|
@ -1300,7 +1284,7 @@ std::string Generator::ModuleLevelServiceDescriptorName(
|
|||
std::string name = absl::StrCat("_", descriptor.name());
|
||||
absl::AsciiStrToUpper(&name);
|
||||
if (descriptor.file() != file_) {
|
||||
name = absl::StrCat(ModuleAlias(descriptor.file()->name()), ".", name);
|
||||
name = absl::StrCat(ModuleAlias(descriptor.file()), ".", name);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
|
@ -1521,8 +1505,8 @@ void Generator::FixOptionsForMessage(const Descriptor& descriptor,
|
|||
void Generator::CopyPublicDependenciesAliases(
|
||||
absl::string_view copy_from, const FileDescriptor* file) const {
|
||||
for (int i = 0; i < file->public_dependency_count(); ++i) {
|
||||
std::string module_name = ModuleName(file->public_dependency(i)->name());
|
||||
std::string module_alias = ModuleAlias(file->public_dependency(i)->name());
|
||||
std::string module_name = ModuleName(file->public_dependency(i));
|
||||
std::string module_alias = ModuleAlias(file->public_dependency(i));
|
||||
// There's no module alias in the dependent file if it was generated by
|
||||
// an old protoc (less than 3.0.0-alpha-1). Use module name in this
|
||||
// situation.
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
|
|||
private:
|
||||
GeneratorOptions ParseParameter(absl::string_view parameter,
|
||||
std::string* error) const;
|
||||
std::string ImportModuleName(absl::string_view filename) const;
|
||||
std::string ImportModuleName(const FileDescriptor* file) const;
|
||||
void PrintImports() const;
|
||||
template <typename DescriptorT>
|
||||
std::string GetResolvedFeatures(const DescriptorT& descriptor) const;
|
||||
|
|
|
|||
|
|
@ -14,11 +14,12 @@
|
|||
#include "absl/log/absl_check.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_replace.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/strings/strip.h"
|
||||
#include "google/protobuf/compiler/code_generator.h"
|
||||
#include "google/protobuf/compiler/python/names.h"
|
||||
#include "google/protobuf/descriptor.h"
|
||||
#include "google/protobuf/descriptor.pb.h"
|
||||
|
||||
|
|
@ -27,18 +28,6 @@ namespace protobuf {
|
|||
namespace compiler {
|
||||
namespace python {
|
||||
|
||||
// Returns the Python module name expected for a given .proto filename.
|
||||
std::string ModuleName(absl::string_view filename) {
|
||||
std::string basename = StripProto(filename);
|
||||
absl::StrReplaceAll({{"-", "_"}, {"/", "."}}, &basename);
|
||||
return absl::StrCat(basename, "_pb2");
|
||||
}
|
||||
|
||||
std::string StrippedModuleName(absl::string_view filename) {
|
||||
std::string module_name = ModuleName(filename);
|
||||
return module_name;
|
||||
}
|
||||
|
||||
// Keywords reserved by the Python language.
|
||||
const char* const kKeywords[] = {
|
||||
"False", "None", "True", "and", "as", "assert",
|
||||
|
|
@ -74,7 +63,7 @@ std::string ResolveKeyword(absl::string_view name) {
|
|||
|
||||
std::string GetFileName(const FileDescriptor* file_des,
|
||||
absl::string_view suffix) {
|
||||
std::string module_name = ModuleName(file_des->name());
|
||||
std::string module_name = ModuleName(file_des);
|
||||
std::string filename = module_name;
|
||||
absl::StrReplaceAll({{".", "/"}}, &filename);
|
||||
absl::StrAppend(&filename, suffix);
|
||||
|
|
|
|||
|
|
@ -10,18 +10,18 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/str_replace.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "google/protobuf/descriptor.h"
|
||||
#include "google/protobuf/descriptor.pb.h"
|
||||
|
||||
// Must be included last.
|
||||
#include "google/protobuf/port_def.inc"
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace python {
|
||||
|
||||
std::string ModuleName(absl::string_view filename);
|
||||
std::string StrippedModuleName(absl::string_view filename);
|
||||
bool ContainsPythonKeyword(absl::string_view module_name);
|
||||
bool IsPythonKeyword(absl::string_view name);
|
||||
std::string ResolveKeyword(absl::string_view name);
|
||||
|
|
@ -40,4 +40,6 @@ std::string NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
|
|||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include "google/protobuf/port_undef.inc"
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_HELPERS_H__
|
||||
|
|
|
|||
45
src/google/protobuf/compiler/python/names.cc
Normal file
45
src/google/protobuf/compiler/python/names.cc
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#include "google/protobuf/compiler/python/names.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_replace.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/strings/strip.h"
|
||||
#include "google/protobuf/compiler/code_generator.h"
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace python {
|
||||
|
||||
// Returns the Python module name expected for a given .proto filename.
|
||||
std::string ModuleName(const FileDescriptor* file) {
|
||||
std::string basename = StripProto(file->name());
|
||||
absl::StrReplaceAll({{"-", "_"}, {"/", "."}}, &basename);
|
||||
return absl::StrCat(basename, "_pb2");
|
||||
}
|
||||
|
||||
std::string StrippedModuleName(const FileDescriptor* file) {
|
||||
std::string module_name = ModuleName(file);
|
||||
return module_name;
|
||||
}
|
||||
|
||||
// Returns the alias we assign to the module of the given .proto filename
|
||||
// when importing. See testPackageInitializationImport in
|
||||
// third_party/py/google/protobuf/internal/reflection_test.py
|
||||
// to see why we need the alias.
|
||||
std::string ModuleAlias(const FileDescriptor* file) {
|
||||
std::string module_name = ModuleName(file);
|
||||
// We can't have dots in the module name, so we replace each with _dot_.
|
||||
// But that could lead to a collision between a.b and a_dot_b, so we also
|
||||
// duplicate each underscore.
|
||||
absl::StrReplaceAll({{"_", "__"}}, &module_name);
|
||||
absl::StrReplaceAll({{".", "_dot_"}}, &module_name);
|
||||
return module_name;
|
||||
}
|
||||
|
||||
} // namespace python
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
36
src/google/protobuf/compiler/python/names.h
Normal file
36
src/google/protobuf/compiler/python/names.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_NAMES_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_PYTHON_NAMES_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
// Must be included last.
|
||||
#include "google/protobuf/port_def.inc"
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
|
||||
class FileDescriptor;
|
||||
|
||||
namespace compiler {
|
||||
namespace python {
|
||||
|
||||
// Returns the Python module name expected for a given .proto filename.
|
||||
PROTOC_EXPORT std::string ModuleName(const FileDescriptor* file);
|
||||
|
||||
// Returns the stripped Python module name expected for a given .proto filename.
|
||||
PROTOC_EXPORT std::string StrippedModuleName(const FileDescriptor* file);
|
||||
|
||||
// Returns the alias we assign to the module of the given .proto filename
|
||||
// when importing. See testPackageInitializationImport in
|
||||
// third_party/py/google/protobuf/internal/reflection_test.py
|
||||
// to see why we need the alias.
|
||||
PROTOC_EXPORT std::string ModuleAlias(const FileDescriptor* file);
|
||||
|
||||
} // namespace python
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include "google/protobuf/port_undef.inc"
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_NAMES_H__
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
#include "absl/synchronization/mutex.h"
|
||||
#include "google/protobuf/compiler/code_generator.h"
|
||||
#include "google/protobuf/compiler/python/helpers.h"
|
||||
#include "google/protobuf/compiler/python/names.h"
|
||||
#include "google/protobuf/descriptor.h"
|
||||
#include "google/protobuf/descriptor.pb.h"
|
||||
#include "google/protobuf/io/printer.h"
|
||||
|
|
@ -45,7 +46,7 @@ std::string PyiGenerator::ModuleLevelName(const DescriptorT& descriptor) const {
|
|||
std::string module_alias;
|
||||
const absl::string_view filename = descriptor.file()->name();
|
||||
if (import_map_.find(filename) == import_map_.end()) {
|
||||
std::string module_name = ModuleName(descriptor.file()->name());
|
||||
std::string module_name = ModuleName(descriptor.file());
|
||||
std::vector<absl::string_view> tokens = absl::StrSplit(module_name, '.');
|
||||
module_alias = absl::StrCat("_", tokens.back());
|
||||
} else {
|
||||
|
|
@ -151,7 +152,7 @@ void PyiGenerator::PrintImportForDescriptor(
|
|||
const FileDescriptor& desc, absl::flat_hash_set<std::string>* seen_aliases,
|
||||
bool* has_importlib) const {
|
||||
const absl::string_view filename = desc.name();
|
||||
std::string module_name_owned = StrippedModuleName(filename);
|
||||
std::string module_name_owned = StrippedModuleName(&desc);
|
||||
absl::string_view module_name(module_name_owned);
|
||||
size_t last_dot_pos = module_name.rfind('.');
|
||||
std::string alias = absl::StrCat("_", module_name.substr(last_dot_pos + 1));
|
||||
|
|
@ -296,7 +297,7 @@ void PyiGenerator::PrintImports() const {
|
|||
// Public imports
|
||||
for (int i = 0; i < file_->public_dependency_count(); ++i) {
|
||||
const FileDescriptor* public_dep = file_->public_dependency(i);
|
||||
std::string module_name = StrippedModuleName(public_dep->name());
|
||||
std::string module_name = StrippedModuleName(public_dep);
|
||||
// Top level messages in public imports
|
||||
for (int i = 0; i < public_dep->message_type_count(); ++i) {
|
||||
printer_->Print(
|
||||
|
|
@ -404,7 +405,7 @@ std::string PyiGenerator::GetFieldType(
|
|||
std::string name = ModuleLevelName(*field_des.message_type());
|
||||
if ((containing_des.containing_type() != nullptr &&
|
||||
name == containing_des.name())) {
|
||||
std::string module = ModuleName(field_des.file()->name());
|
||||
std::string module = ModuleName(field_des.file());
|
||||
name = absl::StrCat(module, ".", name);
|
||||
}
|
||||
return name;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue