aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/protoc/src/google/protobuf/compiler/python
diff options
context:
space:
mode:
authornechda <nechda@yandex-team.com>2024-08-29 23:50:27 +0300
committernechda <nechda@yandex-team.com>2024-08-30 00:05:25 +0300
commite10d6638f07a82edae3ea8197b9f5c0affcc07ea (patch)
tree571c38cec05813766a1ad290c9d51ce7ace52919 /contrib/libs/protoc/src/google/protobuf/compiler/python
parente79b38f2bbbf78d295d1901d2a79f898022d5224 (diff)
downloadydb-e10d6638f07a82edae3ea8197b9f5c0affcc07ea.tar.gz
Update cpp-protobuf to 22.5
Привет!\ Этот PR переключат cpp & python библиотеки protobuf на версию 22.5 Если у вас возникли проблемы после влития этого PR: 1. Если начали падать канон тесты, то проведите их переканонизацию 2. Прочитайте <https://wiki.yandex-team.ru/users/nechda/obnovlenie-cpp-protobuf-22.5/> страничку с основными изменениями 3. Если страничка в вики не помогла, то пишите в [DEVTOOLSSUPPORT](https://st.yandex-team.ru/DEVTOOLSSUPPORT) 7fecade616c20a841b9e9af7b7998bdfc8d2807d
Diffstat (limited to 'contrib/libs/protoc/src/google/protobuf/compiler/python')
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/python/generator.cc526
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/python/generator.h51
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/python/helpers.cc77
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/python/helpers.h21
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/python/pyi_generator.cc408
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/python/pyi_generator.h61
6 files changed, 633 insertions, 511 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/python/generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/python/generator.cc
index d1e4de467b9..aaf5e3f8cb8 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/python/generator.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/python/generator.cc
@@ -42,27 +42,33 @@
// performance-minded Python code leverage the fast C++ implementation
// directly.
-#include <google/protobuf/compiler/python/generator.h>
+#include "google/protobuf/compiler/python/generator.h"
#include <algorithm>
#include <limits>
-#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/stringprintf.h>
-#include <google/protobuf/stubs/substitute.h>
-#include <google/protobuf/compiler/python/helpers.h>
-#include <google/protobuf/compiler/python/pyi_generator.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/io/printer.h>
-#include <google/protobuf/io/zero_copy_stream.h>
+#include "y_absl/container/flat_hash_map.h"
+#include "y_absl/log/absl_check.h"
+#include "y_absl/log/absl_log.h"
+#include "y_absl/strings/ascii.h"
+#include "y_absl/strings/escaping.h"
+#include "y_absl/strings/str_cat.h"
+#include "y_absl/strings/str_format.h"
+#include "y_absl/strings/str_replace.h"
+#include "y_absl/strings/string_view.h"
+#include "y_absl/strings/strip.h"
+#include "y_absl/strings/substitute.h"
+#include "google/protobuf/compiler/python/helpers.h"
+#include "google/protobuf/compiler/python/pyi_generator.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/descriptor.pb.h"
+#include "google/protobuf/io/printer.h"
+#include "google/protobuf/io/strtod.h"
+#include "google/protobuf/io/zero_copy_stream.h"
namespace google {
namespace protobuf {
@@ -72,15 +78,15 @@ namespace python {
namespace {
// Returns the alias we assign to the module of the given .proto filename
// when importing. See testPackageInitializationImport in
-// net/proto2/python/internal/reflection_test.py
+// third_party/py/google/protobuf/internal/reflection_test.py
// to see why we need the alias.
-TProtoStringType ModuleAlias(const TProtoStringType& filename) {
+TProtoStringType ModuleAlias(y_absl::string_view filename) {
TProtoStringType 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.
- GlobalReplaceSubstring("_", "__", &module_name);
- GlobalReplaceSubstring(".", "_dot_", &module_name);
+ y_absl::StrReplaceAll({{"_", "__"}}, &module_name);
+ y_absl::StrReplaceAll({{".", "_dot_"}}, &module_name);
return module_name;
}
@@ -90,29 +96,7 @@ TProtoStringType ModuleAlias(const TProtoStringType& filename) {
// in proto2/public/reflection.py.
const char kDescriptorKey[] = "DESCRIPTOR";
-
-// file output by this generator.
-void PrintTopBoilerplate(io::Printer* printer, const FileDescriptor* file,
- bool descriptor_proto) {
- // TODO(robinson): Allow parameterization of Python version?
- printer->Print(
- "# -*- coding: utf-8 -*-\n"
- "# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
- "# source: $filename$\n"
- "\"\"\"Generated protocol buffer code.\"\"\"\n",
- "filename", file->name());
- printer->Print(
- "from google.protobuf.internal import builder as _builder\n"
- "from google.protobuf import descriptor as _descriptor\n"
- "from google.protobuf import descriptor_pool as "
- "_descriptor_pool\n"
- "from google.protobuf import symbol_database as "
- "_symbol_database\n");
-
- printer->Print("# @@protoc_insertion_point(imports)\n\n");
- printer->Print("_sym_db = _symbol_database.Default()\n");
- printer->Print("\n\n");
-}
+const char kThirdPartyPrefix[] = "google3.third_party.py.";
// Returns a Python literal giving the default value for a field.
// If the field specifies no explicit default value, we'll return
@@ -131,13 +115,13 @@ TProtoStringType StringifyDefaultValue(const FieldDescriptor& field) {
switch (field.cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
- return StrCat(field.default_value_int32());
+ return y_absl::StrCat(field.default_value_int32());
case FieldDescriptor::CPPTYPE_UINT32:
- return StrCat(field.default_value_uint32());
+ return y_absl::StrCat(field.default_value_uint32());
case FieldDescriptor::CPPTYPE_INT64:
- return StrCat(field.default_value_int64());
+ return y_absl::StrCat(field.default_value_int64());
case FieldDescriptor::CPPTYPE_UINT64:
- return StrCat(field.default_value_uint64());
+ return y_absl::StrCat(field.default_value_uint64());
case FieldDescriptor::CPPTYPE_DOUBLE: {
double value = field.default_value_double();
if (value == std::numeric_limits<double>::infinity()) {
@@ -151,7 +135,7 @@ TProtoStringType StringifyDefaultValue(const FieldDescriptor& field) {
// infinity * 0 = nan
return "(1e10000 * 0)";
} else {
- return "float(" + SimpleDtoa(value) + ")";
+ return y_absl::StrCat("float(", io::SimpleDtoa(value), ")");
}
}
case FieldDescriptor::CPPTYPE_FLOAT: {
@@ -167,24 +151,24 @@ TProtoStringType StringifyDefaultValue(const FieldDescriptor& field) {
// infinity - infinity = nan
return "(1e10000 * 0)";
} else {
- return "float(" + SimpleFtoa(value) + ")";
+ return y_absl::StrCat("float(", io::SimpleFtoa(value), ")");
}
}
case FieldDescriptor::CPPTYPE_BOOL:
return field.default_value_bool() ? "True" : "False";
case FieldDescriptor::CPPTYPE_ENUM:
- return StrCat(field.default_value_enum()->number());
+ return y_absl::StrCat(field.default_value_enum()->number());
case FieldDescriptor::CPPTYPE_STRING:
- return "b\"" + CEscape(field.default_value_string()) +
- (field.type() != FieldDescriptor::TYPE_STRING
- ? "\""
- : "\".decode('utf-8')");
+ return y_absl::StrCat("b\"", y_absl::CEscape(field.default_value_string()),
+ (field.type() != FieldDescriptor::TYPE_STRING
+ ? "\""
+ : "\".decode('utf-8')"));
case FieldDescriptor::CPPTYPE_MESSAGE:
return "None";
}
// (We could add a default case above but then we wouldn't get the nice
// compiler warning when a new type is added.)
- GOOGLE_LOG(FATAL) << "Not reached.";
+ Y_ABSL_LOG(FATAL) << "Not reached.";
return "";
}
@@ -196,8 +180,9 @@ TProtoStringType StringifySyntax(FileDescriptor::Syntax syntax) {
return "proto3";
case FileDescriptor::SYNTAX_UNKNOWN:
default:
- GOOGLE_LOG(FATAL) << "Unsupported syntax; this generator only supports proto2 "
- "and proto3 syntax.";
+ Y_ABSL_LOG(FATAL)
+ << "Unsupported syntax; this generator only supports proto2 "
+ "and proto3 syntax.";
return "";
}
}
@@ -212,26 +197,42 @@ uint64_t Generator::GetSupportedFeatures() const {
return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL;
}
+GeneratorOptions Generator::ParseParameter(y_absl::string_view parameter,
+ TProtoStringType* error) const {
+ GeneratorOptions options;
+
+ std::vector<std::pair<TProtoStringType, TProtoStringType> > option_pairs;
+ ParseGeneratorParameter(parameter, &option_pairs);
+
+ for (const std::pair<TProtoStringType, TProtoStringType>& option : option_pairs) {
+ if (!opensource_runtime_ &&
+ option.first == "no_enforce_api_compatibility") {
+ // TODO(b/241584880): remove this legacy option, it has no effect.
+ } else if (!opensource_runtime_ && option.first == "bootstrap") {
+ options.bootstrap = true;
+ } else if (option.first == "pyi_out") {
+ options.generate_pyi = true;
+ } else if (option.first == "annotate_code") {
+ options.annotate_pyi = true;
+ } else {
+ *error = y_absl::StrCat("Unknown generator option: ", option.first);
+ }
+ }
+ return options;
+}
+
bool Generator::Generate(const FileDescriptor* file,
const TProtoStringType& parameter,
GeneratorContext* context, TProtoStringType* error) const {
// -----------------------------------------------------------------
- // parse generator options
- bool cpp_generated_lib_linked = false;
-
- std::vector<std::pair<TProtoStringType, TProtoStringType> > options;
- ParseGeneratorParameter(parameter, &options);
-
- for (int i = 0; i < options.size(); i++) {
- if (options[i].first == "cpp_generated_lib_linked") {
- cpp_generated_lib_linked = true;
- } else if (options[i].first == "pyi_out") {
- python::PyiGenerator pyi_generator;
- if (!pyi_generator.Generate(file, "", context, error)) {
- return false;
- }
- } else {
- *error = "Unknown generator option: " + options[i].first;
+ GeneratorOptions options = ParseParameter(parameter, error);
+ if (!error->empty()) return false;
+
+ // Generate pyi typing information
+ if (options.generate_pyi) {
+ python::PyiGenerator pyi_generator;
+ TProtoStringType pyi_options = options.annotate_pyi ? "annotate_code" : "";
+ if (!pyi_generator.Generate(file, pyi_options, context, error)) {
return false;
}
}
@@ -243,78 +244,110 @@ bool Generator::Generate(const FileDescriptor* file,
// TODO(kenton): The proper thing to do would be to allocate any state on
// the stack and use that, so that the Generator class itself does not need
// to have any mutable members. Then it is implicitly thread-safe.
- MutexLock lock(&mutex_);
+ y_absl::MutexLock lock(&mutex_);
file_ = file;
TProtoStringType filename = GetFileName(file, ".py");
- pure_python_workable_ = !cpp_generated_lib_linked;
- if (HasPrefixString(file->name(), "google/protobuf/")) {
- pure_python_workable_ = true;
- }
FileDescriptorProto fdp;
file_->CopyTo(&fdp);
fdp.SerializeToString(&file_descriptor_serialized_);
+ if (!opensource_runtime_ && GeneratingDescriptorProto()) {
+ TProtoStringType bootstrap_filename =
+ "net/proto2/python/internal/descriptor_pb2.py";
+ if (options.bootstrap) {
+ filename = bootstrap_filename;
+ } else {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+ io::Printer printer(output.get(), '$');
+ printer.Print(
+ "from $internal_package$ import descriptor_pb2\n"
+ "\n",
+ "internal_package", InternalPackage());
+
+ // For static checkers, we need to explicitly assign to the symbols we
+ // publicly export.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ const Descriptor* message = file_->message_type(i);
+ printer.Print("$name$ = descriptor_pb2.$name$\n", "name",
+ message->name());
+ }
+
+ // Sadly some clients access our internal variables (starting with "_").
+ // To support them, we iterate over *all* symbols to expose even the
+ // private ones. Statically type-checked code should (especially) never
+ // use these, so we don't worry about making them available to pytype
+ // checks.
+ printer.Print(
+ "\n"
+ "globals().update(descriptor_pb2.__dict__)\n"
+ "\n");
+
+ printer.Print(
+ "# @@protoc_insertion_point(module_scope)\n"
+ "\n");
+ return true;
+ }
+ }
std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
- GOOGLE_CHECK(output.get());
+ Y_ABSL_CHECK(output.get());
io::Printer printer(output.get(), '$');
printer_ = &printer;
- PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
- if (pure_python_workable_) {
- PrintImports();
- }
+ PrintTopBoilerplate();
+ PrintImports();
PrintFileDescriptor();
- if (pure_python_workable_) {
- if (GeneratingDescriptorProto()) {
- printer_->Print("if _descriptor._USE_C_DESCRIPTORS == False:\n");
- printer_->Indent();
- // Create enums before message descriptors
- PrintAllNestedEnumsInFile();
- PrintMessageDescriptors();
- FixForeignFieldsInDescriptors();
- printer_->Outdent();
- printer_->Print("else:\n");
- printer_->Indent();
- }
- // Find the message descriptors first and then use the message
- // descriptor to find enums.
- printer_->Print(
- "_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())\n");
- if (GeneratingDescriptorProto()) {
- printer_->Outdent();
- }
+ printer_->Print("_globals = globals()\n");
+ if (GeneratingDescriptorProto()) {
+ printer_->Print("if _descriptor._USE_C_DESCRIPTORS == False:\n");
+ printer_->Indent();
+ // Create enums before message descriptors
+ PrintAllNestedEnumsInFile();
+ PrintMessageDescriptors();
+ FixForeignFieldsInDescriptors();
+ printer_->Outdent();
+ printer_->Print("else:\n");
+ printer_->Indent();
+ }
+ // Find the message descriptors first and then use the message
+ // descriptor to find enums.
+ printer_->Print(
+ "_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)\n");
+ if (GeneratingDescriptorProto()) {
+ printer_->Outdent();
}
TProtoStringType module_name = ModuleName(file->name());
+ if (!opensource_runtime_) {
+ module_name =
+ TProtoStringType(y_absl::StripPrefix(module_name, kThirdPartyPrefix));
+ }
printer_->Print(
"_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, '$module_name$', "
- "globals())\n",
+ "_globals)\n",
"module_name", module_name);
- if (pure_python_workable_) {
- printer.Print("if _descriptor._USE_C_DESCRIPTORS == False:\n");
- printer_->Indent();
+ printer.Print("if _descriptor._USE_C_DESCRIPTORS == False:\n");
+ printer_->Indent();
- // We have to fix up the extensions after the message classes themselves,
- // since they need to call static RegisterExtension() methods on these
- // classes.
- FixForeignFieldsInExtensions();
- // Descriptor options may have custom extensions. These custom options
- // can only be successfully parsed after we register corresponding
- // extensions. Therefore we parse all options again here to recognize
- // custom options that may be unknown when we define the descriptors.
- // This does not apply to services because they are not used by extensions.
- FixAllDescriptorOptions();
+ // We have to fix up the extensions after the message classes themselves,
+ // since they need to call static RegisterExtension() methods on these
+ // classes.
+ FixForeignFieldsInExtensions();
+ // Descriptor options may have custom extensions. These custom options
+ // can only be successfully parsed after we register corresponding
+ // extensions. Therefore we parse all options again here to recognize
+ // custom options that may be unknown when we define the descriptors.
+ // This does not apply to services because they are not used by extensions.
+ FixAllDescriptorOptions();
- // Set serialized_start and serialized_end.
- SetSerializedPbInterval();
+ // Set serialized_start and serialized_end.
+ SetSerializedPbInterval();
- printer_->Outdent();
- }
+ printer_->Outdent();
if (HasGenericServices(file)) {
printer_->Print(
- "_builder.BuildServices(DESCRIPTOR, '$module_name$', globals())\n",
+ "_builder.BuildServices(DESCRIPTOR, '$module_name$', _globals)\n",
"module_name", module_name);
}
@@ -323,13 +356,45 @@ bool Generator::Generate(const FileDescriptor* file,
return !printer.failed();
}
+// file output by this generator.
+void Generator::PrintTopBoilerplate() const {
+ // TODO(robinson): Allow parameterization of Python version?
+ printer_->Print(
+ "# -*- coding: utf-8 -*-\n"
+ "# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "# source: $filename$\n"
+ "\"\"\"Generated protocol buffer code.\"\"\"\n",
+ "filename", file_->name());
+ if (!opensource_runtime_) {
+ // This import is needed so that compatibility proto1 compiler output
+ // inserted at protoc_insertion_point can refer to other protos like
+ // google3.a.b.c. Code generated by proto2 compiler doesn't do it, and
+ // instead uses aliases assigned when importing modules.
+ printer_->Print("import google3\n");
+ }
+ printer_->Print(
+ "from $internal_package$ import builder as _builder\n"
+ "from $public_package$ import descriptor as _descriptor\n"
+ "from $public_package$ import descriptor_pool as _descriptor_pool\n"
+ "from $public_package$ import symbol_database as _symbol_database\n",
+ "internal_package", InternalPackage(), "public_package", PublicPackage());
+
+ printer_->Print("# @@protoc_insertion_point(imports)\n\n");
+ printer_->Print("_sym_db = _symbol_database.Default()\n");
+ printer_->Print("\n\n");
+}
+
// Prints Python imports for all modules imported by |file|.
void Generator::PrintImports() const {
for (int i = 0; i < file_->dependency_count(); ++i) {
- const TProtoStringType& filename = file_->dependency(i)->name();
+ y_absl::string_view filename = file_->dependency(i)->name();
TProtoStringType module_name = ModuleName(filename);
TProtoStringType module_alias = ModuleAlias(filename);
+ if (!opensource_runtime_) {
+ module_name =
+ TProtoStringType(y_absl::StripPrefix(module_name, kThirdPartyPrefix));
+ }
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
@@ -339,15 +404,16 @@ void Generator::PrintImports() const {
printer_->Print("$alias$ = importlib.import_module('$name$')\n", "alias",
module_alias, "name", module_name);
} else {
- int last_dot_pos = module_name.rfind('.');
+ size_t last_dot_pos = module_name.rfind('.');
TProtoStringType import_statement;
if (last_dot_pos == TProtoStringType::npos) {
// NOTE(petya): this is not tested as it would require a protocol buffer
// outside of any package, and I don't think that is easily achievable.
- import_statement = "import " + module_name;
+ import_statement = y_absl::StrCat("import ", module_name);
} else {
- import_statement = "from " + module_name.substr(0, last_dot_pos) +
- " import " + module_name.substr(last_dot_pos + 1);
+ import_statement =
+ y_absl::StrCat("from ", module_name.substr(0, last_dot_pos),
+ " import ", module_name.substr(last_dot_pos + 1));
}
printer_->Print("$statement$ as $alias$\n", "statement", import_statement,
"alias", module_alias);
@@ -360,6 +426,10 @@ void Generator::PrintImports() const {
// Print public imports.
for (int i = 0; i < file_->public_dependency_count(); ++i) {
TProtoStringType module_name = ModuleName(file_->public_dependency(i)->name());
+ if (!opensource_runtime_) {
+ module_name =
+ TProtoStringType(y_absl::StripPrefix(module_name, kThirdPartyPrefix));
+ }
printer_->Print("from $module$ import *\n", "module", module_name);
}
printer_->Print("\n");
@@ -367,13 +437,13 @@ void Generator::PrintImports() const {
// Prints the single file descriptor for this file.
void Generator::PrintFileDescriptor() const {
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
m["descriptor_name"] = kDescriptorKey;
m["name"] = file_->name();
m["package"] = file_->package();
m["syntax"] = StringifySyntax(file_->syntax());
m["options"] = OptionsValue(file_->options().SerializeAsString());
- m["serialized_descriptor"] = strings::CHexEscape(file_descriptor_serialized_);
+ m["serialized_descriptor"] = y_absl::CHexEscape(file_descriptor_serialized_);
if (GeneratingDescriptorProto()) {
printer_->Print("if _descriptor._USE_C_DESCRIPTORS == False:\n");
printer_->Indent();
@@ -389,30 +459,26 @@ void Generator::PrintFileDescriptor() const {
" create_key=_descriptor._internal_create_key,\n";
printer_->Print(m, file_descriptor_template);
printer_->Indent();
- if (pure_python_workable_) {
- printer_->Print("serialized_pb=b'$value$'\n", "value",
- strings::CHexEscape(file_descriptor_serialized_));
- if (file_->dependency_count() != 0) {
- printer_->Print(",\ndependencies=[");
- for (int i = 0; i < file_->dependency_count(); ++i) {
- TProtoStringType module_alias = ModuleAlias(file_->dependency(i)->name());
- printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
- module_alias);
- }
- printer_->Print("]");
+ printer_->Print("serialized_pb=b'$value$'\n", "value",
+ y_absl::CHexEscape(file_descriptor_serialized_));
+ if (file_->dependency_count() != 0) {
+ printer_->Print(",\ndependencies=[");
+ for (int i = 0; i < file_->dependency_count(); ++i) {
+ TProtoStringType module_alias = ModuleAlias(file_->dependency(i)->name());
+ printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
+ module_alias);
}
- if (file_->public_dependency_count() > 0) {
- printer_->Print(",\npublic_dependencies=[");
- for (int i = 0; i < file_->public_dependency_count(); ++i) {
- TProtoStringType module_alias =
- ModuleAlias(file_->public_dependency(i)->name());
- printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
- module_alias);
- }
- printer_->Print("]");
+ printer_->Print("]");
+ }
+ if (file_->public_dependency_count() > 0) {
+ printer_->Print(",\npublic_dependencies=[");
+ for (int i = 0; i < file_->public_dependency_count(); ++i) {
+ TProtoStringType module_alias =
+ ModuleAlias(file_->public_dependency(i)->name());
+ printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
+ module_alias);
}
- } else {
- printer_->Print("serialized_pb=''\n");
+ printer_->Print("]");
}
// TODO(falk): Also print options and fix the message_type, enum_type,
@@ -446,7 +512,7 @@ void Generator::PrintAllNestedEnumsInFile() const {
// enum name to a Python EnumDescriptor object equivalent to
// enum_descriptor.
void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
TProtoStringType module_level_descriptor_name =
ModuleLevelDescriptorName(enum_descriptor);
m["descriptor_name"] = module_level_descriptor_name;
@@ -467,11 +533,9 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
printer_->Indent();
printer_->Indent();
- if (pure_python_workable_) {
- for (int i = 0; i < enum_descriptor.value_count(); ++i) {
- PrintEnumValueDescriptor(*enum_descriptor.value(i));
- printer_->Print(",\n");
- }
+ for (int i = 0; i < enum_descriptor.value_count(); ++i) {
+ PrintEnumValueDescriptor(*enum_descriptor.value(i));
+ printer_->Print(",\n");
}
printer_->Outdent();
@@ -482,10 +546,8 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
EnumDescriptorProto edp;
printer_->Outdent();
printer_->Print(")\n");
- if (pure_python_workable_) {
- printer_->Print("_sym_db.RegisterEnumDescriptor($name$)\n", "name",
- module_level_descriptor_name);
- }
+ printer_->Print("_sym_db.RegisterEnumDescriptor($name$)\n", "name",
+ module_level_descriptor_name);
printer_->Print("\n");
}
@@ -525,7 +587,7 @@ void Generator::PrintServices() const {
void Generator::PrintServiceDescriptor(
const ServiceDescriptor& descriptor) const {
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
m["service_name"] = ModuleLevelServiceDescriptorName(descriptor);
m["name"] = descriptor.name();
m["file"] = kDescriptorKey;
@@ -535,13 +597,13 @@ void Generator::PrintServiceDescriptor(
void Generator::PrintDescriptorKeyAndModuleName(
const ServiceDescriptor& descriptor) const {
TProtoStringType name = ModuleLevelServiceDescriptorName(descriptor);
- if (!pure_python_workable_) {
- name = "_descriptor.ServiceDescriptor(full_name='" +
- descriptor.full_name() + "')";
- }
printer_->Print("$descriptor_key$ = $descriptor_name$,\n", "descriptor_key",
kDescriptorKey, "descriptor_name", name);
TProtoStringType module_name = ModuleName(file_->name());
+ if (!opensource_runtime_) {
+ module_name =
+ TProtoStringType(y_absl::StripPrefix(module_name, kThirdPartyPrefix));
+ }
printer_->Print("__module__ = '$module_name$'\n", "module_name", module_name);
}
@@ -575,7 +637,7 @@ void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const {
//
// Mutually recursive with PrintNestedDescriptors().
void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
m["name"] = message_descriptor.name();
m["full_name"] = message_descriptor.full_name();
m["file"] = kDescriptorKey;
@@ -634,8 +696,8 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
for (int i = 0; i < message_descriptor.extension_range_count(); ++i) {
const Descriptor::ExtensionRange* range =
message_descriptor.extension_range(i);
- printer_->Print("($start$, $end$), ", "start", StrCat(range->start),
- "end", StrCat(range->end));
+ printer_->Print("($start$, $end$), ", "start", y_absl::StrCat(range->start),
+ "end", y_absl::StrCat(range->end));
}
printer_->Print("],\n");
printer_->Print("oneofs=[\n");
@@ -645,12 +707,13 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
m.clear();
m["name"] = desc->name();
m["full_name"] = desc->full_name();
- m["index"] = StrCat(desc->index());
+ m["index"] = y_absl::StrCat(desc->index());
options_string = OptionsValue(desc->options().SerializeAsString());
if (options_string == "None") {
m["serialized_options"] = "";
} else {
- m["serialized_options"] = ", serialized_options=" + options_string;
+ m["serialized_options"] =
+ y_absl::StrCat(", serialized_options=", options_string);
}
printer_->Print(m,
"_descriptor.OneofDescriptor(\n"
@@ -699,16 +762,16 @@ void Generator::PrintMessages() const {
// Mutually recursive with PrintNestedMessages().
// Collect nested message names to_register for the symbol_database.
void Generator::PrintMessage(const Descriptor& message_descriptor,
- const TProtoStringType& prefix,
+ y_absl::string_view prefix,
std::vector<TProtoStringType>* to_register,
bool is_nested) const {
TProtoStringType qualified_name;
if (is_nested) {
if (IsPythonKeyword(message_descriptor.name())) {
- qualified_name =
- "getattr(" + prefix + ", '" + message_descriptor.name() + "')";
+ qualified_name = y_absl::StrCat("getattr(", prefix, ", '",
+ message_descriptor.name(), "')");
} else {
- qualified_name = prefix + "." + message_descriptor.name();
+ qualified_name = y_absl::StrCat(prefix, ".", message_descriptor.name());
}
printer_->Print(
"'$name$' : _reflection.GeneratedProtocolMessageType('$name$', "
@@ -726,16 +789,15 @@ void Generator::PrintMessage(const Descriptor& message_descriptor,
to_register->push_back(qualified_name);
PrintNestedMessages(message_descriptor, qualified_name, to_register);
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
m["descriptor_key"] = kDescriptorKey;
- if (pure_python_workable_) {
- m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
- } else {
- m["descriptor_name"] = "_descriptor.Descriptor(full_name='" +
- message_descriptor.full_name() + "')";
- }
+ m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
printer_->Print(m, "'$descriptor_key$' : $descriptor_name$,\n");
TProtoStringType module_name = ModuleName(file_->name());
+ if (!opensource_runtime_) {
+ module_name =
+ TProtoStringType(y_absl::StripPrefix(module_name, kThirdPartyPrefix));
+ }
printer_->Print("'__module__' : '$module_name$'\n", "module_name",
module_name);
printer_->Print("# @@protoc_insertion_point(class_scope:$full_name$)\n",
@@ -747,7 +809,7 @@ void Generator::PrintMessage(const Descriptor& message_descriptor,
// Prints all nested messages within |containing_descriptor|.
// Mutually recursive with PrintMessage().
void Generator::PrintNestedMessages(
- const Descriptor& containing_descriptor, const TProtoStringType& prefix,
+ const Descriptor& containing_descriptor, y_absl::string_view prefix,
std::vector<TProtoStringType>* to_register) const {
for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
printer_->Print("\n");
@@ -782,7 +844,7 @@ void Generator::FixForeignFieldsInDescriptor(
FixContainingTypeInDescriptor(enum_descriptor, &descriptor);
}
for (int i = 0; i < descriptor.oneof_decl_count(); ++i) {
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
const OneofDescriptor* oneof = descriptor.oneof_decl(i);
m["descriptor_name"] = ModuleLevelDescriptorName(descriptor);
m["oneof_name"] = oneof->name();
@@ -801,7 +863,7 @@ void Generator::FixForeignFieldsInDescriptor(
}
void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const {
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
m["descriptor_name"] = kDescriptorKey;
m["message_name"] = descriptor.name();
m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
@@ -813,7 +875,7 @@ void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const {
void Generator::AddServiceToFileDescriptor(
const ServiceDescriptor& descriptor) const {
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
m["descriptor_name"] = kDescriptorKey;
m["service_name"] = descriptor.name();
m["service_descriptor_name"] = ModuleLevelServiceDescriptorName(descriptor);
@@ -825,7 +887,7 @@ void Generator::AddServiceToFileDescriptor(
void Generator::AddEnumToFileDescriptor(
const EnumDescriptor& descriptor) const {
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
m["descriptor_name"] = kDescriptorKey;
m["enum_name"] = descriptor.name();
m["enum_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
@@ -837,7 +899,7 @@ void Generator::AddEnumToFileDescriptor(
void Generator::AddExtensionToFileDescriptor(
const FieldDescriptor& descriptor) const {
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
m["descriptor_name"] = kDescriptorKey;
m["field_name"] = descriptor.name();
m["resolved_name"] = ResolveKeyword(descriptor.name());
@@ -858,10 +920,10 @@ void Generator::AddExtensionToFileDescriptor(
// is NULL.
void Generator::FixForeignFieldsInField(
const Descriptor* containing_type, const FieldDescriptor& field,
- const TProtoStringType& python_dict_name) const {
+ y_absl::string_view python_dict_name) const {
const TProtoStringType field_referencing_expression =
FieldReferencingExpression(containing_type, field, python_dict_name);
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
m["field_ref"] = field_referencing_expression;
const Descriptor* foreign_message_type = field.message_type();
if (foreign_message_type) {
@@ -886,15 +948,15 @@ void Generator::FixForeignFieldsInField(
// is NULL.
TProtoStringType Generator::FieldReferencingExpression(
const Descriptor* containing_type, const FieldDescriptor& field,
- const TProtoStringType& python_dict_name) const {
+ y_absl::string_view python_dict_name) const {
// We should only ever be looking up fields in the current file.
// The only things we refer to from other files are message descriptors.
- GOOGLE_CHECK_EQ(field.file(), file_)
+ Y_ABSL_CHECK_EQ(field.file(), file_)
<< field.file()->name() << " vs. " << file_->name();
if (!containing_type) {
return ResolveKeyword(field.name());
}
- return strings::Substitute("$0.$1['$2']",
+ return y_absl::Substitute("$0.$1['$2']",
ModuleLevelDescriptorName(*containing_type),
python_dict_name, field.name());
}
@@ -955,9 +1017,9 @@ void Generator::FixForeignFieldsInExtensions() const {
void Generator::FixForeignFieldsInExtension(
const FieldDescriptor& extension_field) const {
- GOOGLE_CHECK(extension_field.is_extension());
+ Y_ABSL_CHECK(extension_field.is_extension());
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
// Confusingly, for FieldDescriptors that happen to be extensions,
// containing_type() means "extended type."
// On the other hand, extension_scope() will give us what we normally
@@ -989,10 +1051,10 @@ void Generator::PrintEnumValueDescriptor(
// More circular references. ::sigh::
TProtoStringType options_string;
descriptor.options().SerializeToString(&options_string);
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
m["name"] = descriptor.name();
- m["index"] = StrCat(descriptor.index());
- m["number"] = StrCat(descriptor.number());
+ m["index"] = y_absl::StrCat(descriptor.index());
+ m["number"] = y_absl::StrCat(descriptor.number());
m["options"] = OptionsValue(options_string);
printer_->Print(m,
"_descriptor.EnumValueDescriptor(\n"
@@ -1004,11 +1066,11 @@ void Generator::PrintEnumValueDescriptor(
// Returns a CEscaped string of serialized_options.
TProtoStringType Generator::OptionsValue(
- const TProtoStringType& serialized_options) const {
+ y_absl::string_view serialized_options) const {
if (serialized_options.length() == 0 || GeneratingDescriptorProto()) {
return "None";
} else {
- return "b'" + CEscape(serialized_options) + "'";
+ return y_absl::StrCat("b'", y_absl::CEscape(serialized_options), "'");
}
}
@@ -1017,20 +1079,21 @@ void Generator::PrintFieldDescriptor(const FieldDescriptor& field,
bool is_extension) const {
TProtoStringType options_string;
field.options().SerializeToString(&options_string);
- std::map<TProtoStringType, TProtoStringType> m;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> m;
m["name"] = field.name();
m["full_name"] = field.full_name();
- m["index"] = StrCat(field.index());
- m["number"] = StrCat(field.number());
- m["type"] = StrCat(field.type());
- m["cpp_type"] = StrCat(field.cpp_type());
- m["label"] = StrCat(field.label());
+ m["index"] = y_absl::StrCat(field.index());
+ m["number"] = y_absl::StrCat(field.number());
+ m["type"] = y_absl::StrCat(field.type());
+ m["cpp_type"] = y_absl::StrCat(field.cpp_type());
+ m["label"] = y_absl::StrCat(field.label());
m["has_default_value"] = field.has_default_value() ? "True" : "False";
m["default_value"] = StringifyDefaultValue(field);
m["is_extension"] = is_extension ? "True" : "False";
m["serialized_options"] = OptionsValue(options_string);
- m["json_name"] =
- field.has_json_name() ? ", json_name='" + field.json_name() + "'" : "";
+ m["json_name"] = field.has_json_name()
+ ? y_absl::StrCat(", json_name='", field.json_name(), "'")
+ : "";
// We always set message_type and enum_type to None at this point, and then
// these fields in correctly after all referenced descriptors have been
// defined and/or imported (see FixForeignFieldsInDescriptors()).
@@ -1050,8 +1113,8 @@ void Generator::PrintFieldDescriptor(const FieldDescriptor& field,
// Helper for Print{Fields,Extensions}InDescriptor().
void Generator::PrintFieldDescriptorsInDescriptor(
const Descriptor& message_descriptor, bool is_extension,
- const TProtoStringType& list_variable_name, int (Descriptor::*CountFn)() const,
- const FieldDescriptor* (Descriptor::*GetterFn)(int)const) const {
+ y_absl::string_view list_variable_name, int (Descriptor::*CountFn)() const,
+ const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const {
printer_->Print("$list$=[\n", "list", list_variable_name);
printer_->Indent();
for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) {
@@ -1106,14 +1169,14 @@ TProtoStringType Generator::ModuleLevelDescriptorName(
// The C++ implementation doesn't guard against this either. Leaving
// it for now...
TProtoStringType name = NamePrefixedWithNestedTypes(descriptor, "_");
- ToUpper(&name);
+ y_absl::AsciiStrToUpper(&name);
// Module-private for now. Easy to make public later; almost impossible
// to make private later.
- name = "_" + name;
+ name = y_absl::StrCat("_", name);
// 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 = ModuleAlias(descriptor.file()->name()) + "." + name;
+ name = y_absl::StrCat(ModuleAlias(descriptor.file()->name()), ".", name);
}
return name;
}
@@ -1126,7 +1189,7 @@ TProtoStringType Generator::ModuleLevelMessageName(
const Descriptor& descriptor) const {
TProtoStringType name = NamePrefixedWithNestedTypes(descriptor, ".");
if (descriptor.file() != file_) {
- name = ModuleAlias(descriptor.file()->name()) + "." + name;
+ name = y_absl::StrCat(ModuleAlias(descriptor.file()->name()), ".", name);
}
return name;
}
@@ -1135,15 +1198,24 @@ TProtoStringType Generator::ModuleLevelMessageName(
// descriptor.
TProtoStringType Generator::ModuleLevelServiceDescriptorName(
const ServiceDescriptor& descriptor) const {
- TProtoStringType name = descriptor.name();
- ToUpper(&name);
- name = "_" + name;
+ TProtoStringType name = y_absl::StrCat("_", descriptor.name());
+ y_absl::AsciiStrToUpper(&name);
if (descriptor.file() != file_) {
- name = ModuleAlias(descriptor.file()->name()) + "." + name;
+ name = y_absl::StrCat(ModuleAlias(descriptor.file()->name()), ".", name);
}
return name;
}
+TProtoStringType Generator::PublicPackage() const {
+ return opensource_runtime_ ? "google.protobuf"
+ : "google3.net.google.protobuf.python.public";
+}
+
+TProtoStringType Generator::InternalPackage() const {
+ return opensource_runtime_ ? "google.protobuf.internal"
+ : "google3.net.google.protobuf.python.internal";
+}
+
// Prints standard constructor arguments serialized_start and serialized_end.
// Args:
// descriptor: The cpp descriptor to have a serialized reference.
@@ -1155,23 +1227,23 @@ TProtoStringType Generator::ModuleLevelServiceDescriptorName(
template <typename DescriptorT, typename DescriptorProtoT>
void Generator::PrintSerializedPbInterval(const DescriptorT& descriptor,
DescriptorProtoT& proto,
- const TProtoStringType& name) const {
+ y_absl::string_view name) const {
descriptor.CopyTo(&proto);
TProtoStringType sp;
proto.SerializeToString(&sp);
int offset = file_descriptor_serialized_.find(sp);
- GOOGLE_CHECK_GE(offset, 0);
+ Y_ABSL_CHECK_GE(offset, 0);
printer_->Print(
- "$name$._serialized_start=$serialized_start$\n"
- "$name$._serialized_end=$serialized_end$\n",
- "name", name, "serialized_start", StrCat(offset), "serialized_end",
- StrCat(offset + sp.size()));
+ "_globals['$name$']._serialized_start=$serialized_start$\n"
+ "_globals['$name$']._serialized_end=$serialized_end$\n",
+ "name", name, "serialized_start", y_absl::StrCat(offset), "serialized_end",
+ y_absl::StrCat(offset + sp.size()));
}
namespace {
-void PrintDescriptorOptionsFixingCode(const TProtoStringType& descriptor,
- const TProtoStringType& options,
+void PrintDescriptorOptionsFixingCode(y_absl::string_view descriptor,
+ y_absl::string_view options,
io::Printer* printer) {
// Reset the _options to None thus DescriptorBase.GetOptions() can
// parse _options again after extensions are registered.
@@ -1256,7 +1328,7 @@ void Generator::FixAllDescriptorOptions() const {
void Generator::FixOptionsForOneof(const OneofDescriptor& oneof) const {
TProtoStringType oneof_options = OptionsValue(oneof.options().SerializeAsString());
if (oneof_options != "None") {
- TProtoStringType oneof_name = strings::Substitute(
+ TProtoStringType oneof_name = y_absl::Substitute(
"$0.$1['$2']", ModuleLevelDescriptorName(*oneof.containing_type()),
"oneofs_by_name", oneof.name());
PrintDescriptorOptionsFixingCode(oneof_name, oneof_options, printer_);
@@ -1278,7 +1350,7 @@ void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const {
OptionsValue(value_descriptor.options().SerializeAsString());
if (value_options != "None") {
PrintDescriptorOptionsFixingCode(
- StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(),
+ y_absl::StrFormat("%s.values_by_name[\"%s\"]", descriptor_name.c_str(),
value_descriptor.name().c_str()),
value_options, printer_);
}
@@ -1303,8 +1375,8 @@ void Generator::FixOptionsForService(
TProtoStringType method_options =
OptionsValue(method->options().SerializeAsString());
if (method_options != "None") {
- TProtoStringType method_name =
- descriptor_name + ".methods_by_name['" + method->name() + "']";
+ TProtoStringType method_name = y_absl::StrCat(
+ descriptor_name, ".methods_by_name['", method->name(), "']");
PrintDescriptorOptionsFixingCode(method_name, method_options, printer_);
}
}
@@ -1370,7 +1442,7 @@ void Generator::FixOptionsForMessage(const Descriptor& descriptor) const {
// If a dependency forwards other files through public dependencies, let's
// copy over the corresponding module aliases.
void Generator::CopyPublicDependenciesAliases(
- const TProtoStringType& copy_from, const FileDescriptor* file) const {
+ y_absl::string_view copy_from, const FileDescriptor* file) const {
for (int i = 0; i < file->public_dependency_count(); ++i) {
TProtoStringType module_name = ModuleName(file->public_dependency(i)->name());
TProtoStringType module_alias = ModuleAlias(file->public_dependency(i)->name());
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/python/generator.h b/contrib/libs/protoc/src/google/protobuf/compiler/python/generator.h
index 8111bf733fc..8691b552219 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/python/generator.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/python/generator.h
@@ -36,12 +36,14 @@
#define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
#include <string>
+#include <vector>
-#include <google/protobuf/stubs/mutex.h>
-#include <google/protobuf/compiler/code_generator.h>
+#include "y_absl/strings/string_view.h"
+#include "y_absl/synchronization/mutex.h"
+#include "google/protobuf/compiler/code_generator.h"
// Must be included last.
-#include <google/protobuf/port_def.inc>
+#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
@@ -64,9 +66,18 @@ namespace python {
// If you create your own protocol compiler binary and you want it to support
// Python output, you can do so by registering an instance of this
// CodeGenerator with the CommandLineInterface in your main() function.
+
+struct GeneratorOptions {
+ bool generate_pyi = false;
+ bool annotate_pyi = false;
+ bool bootstrap = false;
+};
+
class PROTOC_EXPORT Generator : public CodeGenerator {
public:
Generator();
+ Generator(const Generator&) = delete;
+ Generator& operator=(const Generator&) = delete;
~Generator() override;
// CodeGenerator methods.
@@ -76,7 +87,13 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
uint64_t GetSupportedFeatures() const override;
+ void set_opensource_runtime(bool opensource) {
+ opensource_runtime_ = opensource;
+ }
+
private:
+ GeneratorOptions ParseParameter(y_absl::string_view parameter,
+ TProtoStringType* error) const;
void PrintImports() const;
void PrintFileDescriptor() const;
void PrintAllNestedEnumsInFile() const;
@@ -87,8 +104,8 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
bool is_extension) const;
void PrintFieldDescriptorsInDescriptor(
const Descriptor& message_descriptor, bool is_extension,
- const TProtoStringType& list_variable_name, int (Descriptor::*CountFn)() const,
- const FieldDescriptor* (Descriptor::*GetterFn)(int)const) const;
+ y_absl::string_view list_variable_name, int (Descriptor::*CountFn)() const,
+ const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const;
void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const;
void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const;
void PrintMessageDescriptors() const;
@@ -97,11 +114,11 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
void PrintMessages() const;
void PrintMessage(const Descriptor& message_descriptor,
- const TProtoStringType& prefix,
+ y_absl::string_view prefix,
std::vector<TProtoStringType>* to_register,
bool is_nested) const;
void PrintNestedMessages(const Descriptor& containing_descriptor,
- const TProtoStringType& prefix,
+ y_absl::string_view prefix,
std::vector<TProtoStringType>* to_register) const;
void FixForeignFieldsInDescriptors() const;
@@ -110,14 +127,14 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
const Descriptor* containing_descriptor) const;
void FixForeignFieldsInField(const Descriptor* containing_type,
const FieldDescriptor& field,
- const TProtoStringType& python_dict_name) const;
+ y_absl::string_view python_dict_name) const;
void AddMessageToFileDescriptor(const Descriptor& descriptor) const;
void AddEnumToFileDescriptor(const EnumDescriptor& descriptor) const;
void AddExtensionToFileDescriptor(const FieldDescriptor& descriptor) const;
void AddServiceToFileDescriptor(const ServiceDescriptor& descriptor) const;
TProtoStringType FieldReferencingExpression(
const Descriptor* containing_type, const FieldDescriptor& field,
- const TProtoStringType& python_dict_name) const;
+ y_absl::string_view python_dict_name) const;
template <typename DescriptorT>
void FixContainingTypeInDescriptor(
const DescriptorT& descriptor,
@@ -128,6 +145,7 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
const FieldDescriptor& extension_field) const;
void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const;
+ void PrintTopBoilerplate() const;
void PrintServices() const;
void PrintServiceDescriptors() const;
void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const;
@@ -137,7 +155,7 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
const ServiceDescriptor& descriptor) const;
void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const;
- TProtoStringType OptionsValue(const TProtoStringType& serialized_options) const;
+ TProtoStringType OptionsValue(y_absl::string_view serialized_options) const;
bool GeneratingDescriptorProto() const;
template <typename DescriptorT>
@@ -145,11 +163,13 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
TProtoStringType ModuleLevelMessageName(const Descriptor& descriptor) const;
TProtoStringType ModuleLevelServiceDescriptorName(
const ServiceDescriptor& descriptor) const;
+ TProtoStringType PublicPackage() const;
+ TProtoStringType InternalPackage() const;
template <typename DescriptorT, typename DescriptorProtoT>
void PrintSerializedPbInterval(const DescriptorT& descriptor,
DescriptorProtoT& proto,
- const TProtoStringType& name) const;
+ y_absl::string_view name) const;
void FixAllDescriptorOptions() const;
void FixOptionsForField(const FieldDescriptor& field) const;
@@ -161,18 +181,17 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
void SetSerializedPbInterval() const;
void SetMessagePbInterval(const Descriptor& descriptor) const;
- void CopyPublicDependenciesAliases(const TProtoStringType& copy_from,
+ void CopyPublicDependenciesAliases(y_absl::string_view copy_from,
const FileDescriptor* file) const;
// Very coarse-grained lock to ensure that Generate() is reentrant.
// Guards file_, printer_ and file_descriptor_serialized_.
- mutable Mutex mutex_;
+ mutable y_absl::Mutex mutex_;
mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_.
mutable TProtoStringType file_descriptor_serialized_;
mutable io::Printer* printer_; // Set in Generate(). Under mutex_.
- mutable bool pure_python_workable_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator);
+ bool opensource_runtime_ = true;
};
} // namespace python
@@ -180,6 +199,6 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
} // namespace protobuf
} // namespace google
-#include <google/protobuf/port_undef.inc>
+#include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/python/helpers.cc b/contrib/libs/protoc/src/google/protobuf/compiler/python/helpers.cc
index ee7461bc83c..f41603420cc 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/python/helpers.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/python/helpers.cc
@@ -28,36 +28,45 @@
// (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 <google/protobuf/compiler/python/helpers.h>
+#include "google/protobuf/compiler/python/helpers.h"
#include <algorithm>
-
-#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/compiler/code_generator.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/descriptor.pb.h>
+#include <string>
+#include <vector>
+
+#include "y_absl/log/absl_check.h"
+#include "y_absl/strings/escaping.h"
+#include "y_absl/strings/match.h"
+#include "y_absl/strings/str_replace.h"
+#include "y_absl/strings/str_split.h"
+#include "y_absl/strings/string_view.h"
+#include "y_absl/strings/strip.h"
+#include "google/protobuf/compiler/code_generator.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/descriptor.pb.h"
namespace google {
namespace protobuf {
namespace compiler {
namespace python {
-TProtoStringType FixEv(const TProtoStringType& filename) {
- if (HasSuffixString(filename, ".ev")) {
- return StripSuffixString(filename, ".ev") + "_ev.proto";
- }
- return filename;
+TProtoStringType FixEv(TProtoStringType filename) {
+ constexpr auto kSuffixLen = 3;
+ if (filename.EndsWith(".ev")) {
+ return filename.substr(0, filename.length() - kSuffixLen) + "_ev.proto";
+ }
+ return filename;
}
// Returns the Python module name expected for a given .proto filename.
-TProtoStringType ModuleName(const TProtoStringType& filename) {
- TProtoStringType basename = StripProto(FixEv(filename));
- ReplaceCharacters(&basename, "-", '_');
- ReplaceCharacters(&basename, "/", '.');
- return basename + "_pb2";
+TProtoStringType ModuleName(y_absl::string_view filename) {
+ TProtoStringType str(std::string{filename});
+ TProtoStringType basename = StripProto(FixEv(str));
+ y_absl::StrReplaceAll({{"-", "_"}, {"/", "."}}, &basename);
+ return y_absl::StrCat(basename, "_pb2");
}
-TProtoStringType StrippedModuleName(const TProtoStringType& filename) {
+TProtoStringType StrippedModuleName(y_absl::string_view filename) {
TProtoStringType module_name = ModuleName(filename);
return module_name;
}
@@ -74,8 +83,8 @@ const char* const kKeywords[] = {
const char* const* kKeywordsEnd =
kKeywords + (sizeof(kKeywords) / sizeof(kKeywords[0]));
-bool ContainsPythonKeyword(const TProtoStringType& module_name) {
- std::vector<TProtoStringType> tokens = Split(module_name, ".");
+bool ContainsPythonKeyword(y_absl::string_view module_name) {
+ std::vector<y_absl::string_view> tokens = y_absl::StrSplit(module_name, '.');
for (int i = 0; i < static_cast<int>(tokens.size()); ++i) {
if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) {
return true;
@@ -84,23 +93,23 @@ bool ContainsPythonKeyword(const TProtoStringType& module_name) {
return false;
}
-bool IsPythonKeyword(const TProtoStringType& name) {
+bool IsPythonKeyword(y_absl::string_view name) {
return (std::find(kKeywords, kKeywordsEnd, name) != kKeywordsEnd);
}
-TProtoStringType ResolveKeyword(const TProtoStringType& name) {
+TProtoStringType ResolveKeyword(y_absl::string_view name) {
if (IsPythonKeyword(name)) {
- return "globals()['" + name + "']";
+ return y_absl::StrCat("globals()['", name, "']");
}
- return name;
+ return TProtoStringType(name);
}
TProtoStringType GetFileName(const FileDescriptor* file_des,
- const TProtoStringType& suffix) {
+ y_absl::string_view suffix) {
TProtoStringType module_name = ModuleName(file_des->name());
TProtoStringType filename = module_name;
- ReplaceCharacters(&filename, ".", '/');
- filename += suffix;
+ y_absl::StrReplaceAll({{".", "/"}}, &filename);
+ y_absl::StrAppend(&filename, suffix);
return filename;
}
@@ -108,17 +117,23 @@ bool HasGenericServices(const FileDescriptor* file) {
return file->service_count() > 0 && file->options().py_generic_services();
}
+TProtoStringType GeneratedCodeToBase64(const GeneratedCodeInfo& annotations) {
+ TProtoStringType result;
+ y_absl::Base64Escape(annotations.SerializeAsString(), &result);
+ return result;
+}
+
template <typename DescriptorT>
TProtoStringType NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
- const TProtoStringType& separator) {
+ y_absl::string_view separator) {
TProtoStringType name = descriptor.name();
const Descriptor* parent = descriptor.containing_type();
if (parent != nullptr) {
TProtoStringType prefix = NamePrefixedWithNestedTypes(*parent, separator);
if (separator == "." && IsPythonKeyword(name)) {
- return "getattr(" + prefix + ", '" + name + "')";
+ return y_absl::StrCat("getattr(", prefix, ", '", name, "')");
} else {
- return prefix + separator + name;
+ return y_absl::StrCat(prefix, separator, name);
}
}
if (separator == ".") {
@@ -128,9 +143,9 @@ TProtoStringType NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
}
template TProtoStringType NamePrefixedWithNestedTypes<Descriptor>(
- const Descriptor& descriptor, const TProtoStringType& separator);
+ const Descriptor& descriptor, y_absl::string_view separator);
template TProtoStringType NamePrefixedWithNestedTypes<EnumDescriptor>(
- const EnumDescriptor& descriptor, const TProtoStringType& separator);
+ const EnumDescriptor& descriptor, y_absl::string_view separator);
} // namespace python
} // namespace compiler
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/python/helpers.h b/contrib/libs/protoc/src/google/protobuf/compiler/python/helpers.h
index 8745698acf6..5d77d73394f 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/python/helpers.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/python/helpers.h
@@ -33,26 +33,29 @@
#include <string>
-#include <google/protobuf/descriptor.h>
+#include "y_absl/strings/str_replace.h"
+#include "y_absl/strings/string_view.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/descriptor.pb.h"
namespace google {
namespace protobuf {
namespace compiler {
namespace python {
-
-TProtoStringType ModuleName(const TProtoStringType& filename);
-TProtoStringType StrippedModuleName(const TProtoStringType& filename);
-bool ContainsPythonKeyword(const TProtoStringType& module_name);
-bool IsPythonKeyword(const TProtoStringType& name);
-TProtoStringType ResolveKeyword(const TProtoStringType& name);
+TProtoStringType ModuleName(y_absl::string_view filename);
+TProtoStringType StrippedModuleName(y_absl::string_view filename);
+bool ContainsPythonKeyword(y_absl::string_view module_name);
+bool IsPythonKeyword(y_absl::string_view name);
+TProtoStringType ResolveKeyword(y_absl::string_view name);
TProtoStringType GetFileName(const FileDescriptor* file_des,
- const TProtoStringType& suffix);
+ y_absl::string_view suffix);
bool HasGenericServices(const FileDescriptor* file);
+TProtoStringType GeneratedCodeToBase64(const GeneratedCodeInfo& annotations);
template <typename DescriptorT>
TProtoStringType NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
- const TProtoStringType& separator);
+ y_absl::string_view separator);
} // namespace python
} // namespace compiler
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/python/pyi_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/python/pyi_generator.cc
index 242cdd71f2c..3e7c2538958 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/python/pyi_generator.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/python/pyi_generator.cc
@@ -28,61 +28,61 @@
// (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 <google/protobuf/compiler/python/pyi_generator.h>
+#include "google/protobuf/compiler/python/pyi_generator.h"
#include <string>
-
-#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/compiler/python/helpers.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/io/printer.h>
-#include <google/protobuf/io/zero_copy_stream.h>
+#include <utility>
+#include <vector>
+
+#include "y_absl/container/flat_hash_set.h"
+#include "y_absl/log/absl_check.h"
+#include "y_absl/log/absl_log.h"
+#include "y_absl/strings/ascii.h"
+#include "y_absl/strings/match.h"
+#include "y_absl/strings/str_split.h"
+#include "google/protobuf/compiler/python/helpers.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/descriptor.pb.h"
+#include "google/protobuf/io/printer.h"
+#include "google/protobuf/io/zero_copy_stream.h"
namespace google {
namespace protobuf {
namespace compiler {
namespace python {
-template <typename DescriptorT>
-struct SortByName {
- bool operator()(const DescriptorT* l, const DescriptorT* r) const {
- return l->name() < r->name();
- }
-};
-
PyiGenerator::PyiGenerator() : file_(nullptr) {}
PyiGenerator::~PyiGenerator() {}
-void PyiGenerator::PrintItemMap(
- const std::map<TProtoStringType, TProtoStringType>& item_map) const {
- for (const auto& entry : item_map) {
- printer_->Print("$key$: $value$\n", "key", entry.first, "value",
- entry.second);
- }
-}
-
template <typename DescriptorT>
-TProtoStringType PyiGenerator::ModuleLevelName(
- const DescriptorT& descriptor,
- const std::map<TProtoStringType, TProtoStringType>& import_map) const {
+TProtoStringType PyiGenerator::ModuleLevelName(const DescriptorT& descriptor) const {
TProtoStringType name = NamePrefixedWithNestedTypes(descriptor, ".");
if (descriptor.file() != file_) {
TProtoStringType module_alias;
TProtoStringType filename = descriptor.file()->name();
- if (import_map.find(filename) == import_map.end()) {
+ if (import_map_.find(filename) == import_map_.end()) {
TProtoStringType module_name = ModuleName(descriptor.file()->name());
- std::vector<TProtoStringType> tokens = Split(module_name, ".");
- module_alias = "_" + tokens.back();
+ std::vector<y_absl::string_view> tokens = y_absl::StrSplit(module_name, '.');
+ module_alias = y_absl::StrCat("_", tokens.back());
} else {
- module_alias = import_map.at(filename);
+ module_alias = import_map_.at(filename);
}
- name = module_alias + "." + name;
+ name = y_absl::StrCat(module_alias, ".", name);
}
return name;
}
+TProtoStringType PyiGenerator::PublicPackage() const {
+ return opensource_runtime_ ? "google.protobuf"
+ : "google3.net.google.protobuf.python.public";
+}
+
+TProtoStringType PyiGenerator::InternalPackage() const {
+ return opensource_runtime_ ? "google.protobuf.internal"
+ : "google3.net.google.protobuf.python.internal";
+}
+
struct ImportModules {
bool has_repeated = false; // _containers
bool has_iterable = false; // typing.Iterable
@@ -156,41 +156,40 @@ void CheckImportModules(const Descriptor* descriptor,
void PyiGenerator::PrintImportForDescriptor(
const FileDescriptor& desc,
- std::map<TProtoStringType, TProtoStringType>* import_map,
- std::set<TProtoStringType>* seen_aliases) const {
+ y_absl::flat_hash_set<TProtoStringType>* seen_aliases) const {
const TProtoStringType& filename = desc.name();
- TProtoStringType module_name = StrippedModuleName(filename);
+ TProtoStringType module_name_owned = StrippedModuleName(filename);
+ y_absl::string_view module_name(module_name_owned);
size_t last_dot_pos = module_name.rfind('.');
TProtoStringType import_statement;
if (last_dot_pos == TProtoStringType::npos) {
- import_statement = "import " + module_name;
+ import_statement = y_absl::StrCat("import ", module_name);
} else {
- import_statement = "from " + module_name.substr(0, last_dot_pos) +
- " import " + module_name.substr(last_dot_pos + 1);
+ import_statement =
+ y_absl::StrCat("from ", module_name.substr(0, last_dot_pos), " import ",
+ module_name.substr(last_dot_pos + 1));
module_name = module_name.substr(last_dot_pos + 1);
}
- TProtoStringType alias = "_" + module_name;
+ TProtoStringType alias = y_absl::StrCat("_", module_name);
// Generate a unique alias by adding _1 suffixes until we get an unused alias.
while (seen_aliases->find(alias) != seen_aliases->end()) {
- alias = alias + "_1";
+ y_absl::StrAppend(&alias, "_1");
}
printer_->Print("$statement$ as $alias$\n", "statement",
import_statement, "alias", alias);
- (*import_map)[filename] = alias;
+ import_map_[filename] = alias;
seen_aliases->insert(alias);
}
-void PyiGenerator::PrintImports(
- std::map<TProtoStringType, TProtoStringType>* item_map,
- std::map<TProtoStringType, TProtoStringType>* import_map) const {
+void PyiGenerator::PrintImports() const {
// Prints imported dependent _pb2 files.
- std::set<TProtoStringType> seen_aliases;
+ y_absl::flat_hash_set<TProtoStringType> seen_aliases;
for (int i = 0; i < file_->dependency_count(); ++i) {
const FileDescriptor* dep = file_->dependency(i);
- PrintImportForDescriptor(*dep, import_map, &seen_aliases);
+ PrintImportForDescriptor(*dep, &seen_aliases);
for (int j = 0; j < dep->public_dependency_count(); ++j) {
PrintImportForDescriptor(
- *dep->public_dependency(j), import_map, &seen_aliases);
+ *dep->public_dependency(j), &seen_aliases);
}
}
@@ -202,6 +201,10 @@ void PyiGenerator::PrintImports(
if (file_->enum_type_count() > 0) {
import_modules.has_enums = true;
}
+ if (!opensource_runtime_ && file_->service_count() > 0) {
+ import_modules.has_optional = true;
+ import_modules.has_union = true;
+ }
for (int i = 0; i < file_->message_type_count(); i++) {
CheckImportModules(file_->message_type(i), &import_modules);
}
@@ -210,37 +213,50 @@ void PyiGenerator::PrintImports(
// required in the proto file.
if (import_modules.has_repeated) {
printer_->Print(
- "from google.protobuf.internal import containers as "
- "_containers\n");
+ "from $internal_package$ import containers as _containers\n",
+ "internal_package", InternalPackage());
}
if (import_modules.has_enums) {
printer_->Print(
- "from google.protobuf.internal import enum_type_wrapper"
- " as _enum_type_wrapper\n");
+ "from $internal_package$ import enum_type_wrapper as "
+ "_enum_type_wrapper\n",
+ "internal_package", InternalPackage());
}
if (import_modules.has_extendable) {
printer_->Print(
- "from google.protobuf.internal import python_message"
- " as _python_message\n");
+ "from $internal_package$ import python_message as _python_message\n",
+ "internal_package", InternalPackage());
}
if (import_modules.has_well_known_type) {
printer_->Print(
- "from google.protobuf.internal import well_known_types"
- " as _well_known_types\n");
+ "from $internal_package$ import well_known_types as "
+ "_well_known_types\n",
+ "internal_package", InternalPackage());
}
- printer_->Print(
- "from google.protobuf import"
- " descriptor as _descriptor\n");
+ printer_->Print("from $public_package$ import descriptor as _descriptor\n",
+ "public_package", PublicPackage());
if (import_modules.has_messages) {
- printer_->Print(
- "from google.protobuf import message as _message\n");
+ printer_->Print("from $public_package$ import message as _message\n",
+ "public_package", PublicPackage());
}
- if (HasGenericServices(file_)) {
- printer_->Print(
- "from google.protobuf import service as"
- " _service\n");
+ if (opensource_runtime_) {
+ if (HasGenericServices(file_)) {
+ printer_->Print("from $public_package$ import service as _service\n",
+ "public_package", PublicPackage());
+ }
+ } else {
+ if (file_->service_count() > 0) {
+ printer_->Print(
+ "from google3.net.rpc.python import proto_python_api_2_stub as "
+ "_proto_python_api_2_stub\n"
+ "from google3.net.rpc.python import pywraprpc as _pywraprpc\n"
+ "from google3.net.rpc.python import rpcserver as _rpcserver\n");
+ }
}
printer_->Print("from typing import ");
+ if (!opensource_runtime_ && file_->service_count() > 0) {
+ printer_->Print("Any as _Any, ");
+ }
printer_->Print("ClassVar as _ClassVar");
if (import_modules.has_iterable) {
printer_->Print(", Iterable as _Iterable");
@@ -254,7 +270,7 @@ void PyiGenerator::PrintImports(
if (import_modules.has_union) {
printer_->Print(", Union as _Union");
}
- printer_->Print("\n\n");
+ printer_->Print("\n");
// Public imports
for (int i = 0; i < file_->public_dependency_count(); ++i) {
@@ -272,17 +288,16 @@ void PyiGenerator::PrintImports(
module_name, "enum_class",
public_dep->enum_type(i)->name());
}
- // Enum values for public imports
- for (int i = 0; i < public_dep->enum_type_count(); ++i) {
- const EnumDescriptor* enum_descriptor = public_dep->enum_type(i);
- for (int j = 0; j < enum_descriptor->value_count(); ++j) {
- (*item_map)[enum_descriptor->value(j)->name()] =
- ModuleLevelName(*enum_descriptor, *import_map);
- }
- }
- // Top level extensions for public imports
- AddExtensions(*public_dep, item_map);
}
+printer_->Print("\n");
+}
+
+// Annotate wrapper for debugging purposes
+// Print a message after Annotate to see what is annotated.
+template <typename DescriptorT>
+void PyiGenerator::Annotate(const TProtoStringType& label,
+ const DescriptorT* descriptor) const {
+printer_->Annotate(label.c_str(), descriptor);
}
void PyiGenerator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
@@ -291,22 +306,31 @@ void PyiGenerator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
"class $enum_name$(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):\n"
" __slots__ = []\n",
"enum_name", enum_name);
+ Annotate("enum_name", &enum_descriptor);
+ printer_->Indent();
+ PrintEnumValues(enum_descriptor, /* is_classvar = */ true);
+ printer_->Outdent();
}
-// Adds enum value to item map which will be ordered and printed later.
-void PyiGenerator::AddEnumValue(
- const EnumDescriptor& enum_descriptor,
- std::map<TProtoStringType, TProtoStringType>* item_map,
- const std::map<TProtoStringType, TProtoStringType>& import_map) const {
+void PyiGenerator::PrintEnumValues(const EnumDescriptor& enum_descriptor,
+ bool is_classvar) const {
// enum values
- TProtoStringType module_enum_name = ModuleLevelName(enum_descriptor, import_map);
+ TProtoStringType module_enum_name = ModuleLevelName(enum_descriptor);
for (int j = 0; j < enum_descriptor.value_count(); ++j) {
const EnumValueDescriptor* value_descriptor = enum_descriptor.value(j);
- (*item_map)[value_descriptor->name()] = module_enum_name;
+ if (is_classvar) {
+ printer_->Print("$name$: _ClassVar[$module_enum_name$]\n", "name",
+ value_descriptor->name(), "module_enum_name",
+ module_enum_name);
+ } else {
+ printer_->Print("$name$: $module_enum_name$\n", "name",
+ value_descriptor->name(), "module_enum_name",
+ module_enum_name);
+ }
+ Annotate("name", value_descriptor);
}
}
-// Prints top level enums
void PyiGenerator::PrintTopLevelEnums() const {
for (int i = 0; i < file_->enum_type_count(); ++i) {
printer_->Print("\n");
@@ -314,25 +338,24 @@ void PyiGenerator::PrintTopLevelEnums() const {
}
}
-// Add top level extensions to item_map which will be ordered and
-// printed later.
template <typename DescriptorT>
-void PyiGenerator::AddExtensions(
- const DescriptorT& descriptor,
- std::map<TProtoStringType, TProtoStringType>* item_map) const {
+void PyiGenerator::PrintExtensions(const DescriptorT& descriptor) const {
for (int i = 0; i < descriptor.extension_count(); ++i) {
const FieldDescriptor* extension_field = descriptor.extension(i);
- TProtoStringType constant_name = extension_field->name() + "_FIELD_NUMBER";
- ToUpper(&constant_name);
- (*item_map)[constant_name] = "_ClassVar[int]";
- (*item_map)[extension_field->name()] = "_descriptor.FieldDescriptor";
+ TProtoStringType constant_name =
+ y_absl::StrCat(extension_field->name(), "_FIELD_NUMBER");
+ y_absl::AsciiStrToUpper(&constant_name);
+ printer_->Print("$constant_name$: _ClassVar[int]\n",
+ "constant_name", constant_name);
+ printer_->Print("$name$: _descriptor.FieldDescriptor\n",
+ "name", extension_field->name());
+ Annotate("name", extension_field);
}
}
// Returns the string format of a field's cpp_type
TProtoStringType PyiGenerator::GetFieldType(
- const FieldDescriptor& field_des, const Descriptor& containing_des,
- const std::map<TProtoStringType, TProtoStringType>& import_map) const {
+ const FieldDescriptor& field_des, const Descriptor& containing_des) const {
switch (field_des.cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
case FieldDescriptor::CPPTYPE_UINT32:
@@ -345,7 +368,7 @@ TProtoStringType PyiGenerator::GetFieldType(
case FieldDescriptor::CPPTYPE_BOOL:
return "bool";
case FieldDescriptor::CPPTYPE_ENUM:
- return ModuleLevelName(*field_des.enum_type(), import_map);
+ return ModuleLevelName(*field_des.enum_type());
case FieldDescriptor::CPPTYPE_STRING:
if (field_des.type() == FieldDescriptor::TYPE_STRING) {
return "str";
@@ -356,23 +379,22 @@ TProtoStringType PyiGenerator::GetFieldType(
// If the field is inside a nested message and the nested message has the
// same name as a top-level message, then we need to prefix the field type
// with the module name for disambiguation.
- TProtoStringType name = ModuleLevelName(*field_des.message_type(), import_map);
+ TProtoStringType name = ModuleLevelName(*field_des.message_type());
if ((containing_des.containing_type() != nullptr &&
name == containing_des.name())) {
TProtoStringType module = ModuleName(field_des.file()->name());
- name = module + "." + name;
+ name = y_absl::StrCat(module, ".", name);
}
return name;
}
default:
- GOOGLE_LOG(FATAL) << "Unsupported field type.";
+ Y_ABSL_LOG(FATAL) << "Unsupported field type.";
}
return "";
}
void PyiGenerator::PrintMessage(
- const Descriptor& message_descriptor, bool is_nested,
- const std::map<TProtoStringType, TProtoStringType>& import_map) const {
+ const Descriptor& message_descriptor, bool is_nested) const {
if (!is_nested) {
printer_->Print("\n");
}
@@ -381,26 +403,21 @@ void PyiGenerator::PrintMessage(
// A well-known type needs to inherit from its corresponding base class in
// net/proto2/python/internal/well_known_types.
if (IsWellKnownType(message_descriptor.full_name())) {
- extra_base = ", _well_known_types." + message_descriptor.name();
+ extra_base =
+ y_absl::StrCat(", _well_known_types.", message_descriptor.name());
} else {
extra_base = "";
}
printer_->Print("class $class_name$(_message.Message$extra_base$):\n",
"class_name", class_name, "extra_base", extra_base);
+ Annotate("class_name", &message_descriptor);
printer_->Indent();
- printer_->Indent();
-
- std::vector<const FieldDescriptor*> fields;
- fields.reserve(message_descriptor.field_count());
- for (int i = 0; i < message_descriptor.field_count(); ++i) {
- fields.push_back(message_descriptor.field(i));
- }
- std::sort(fields.begin(), fields.end(), SortByName<FieldDescriptor>());
// Prints slots
printer_->Print("__slots__ = [", "class_name", class_name);
bool first_item = true;
- for (const auto& field_des : fields) {
+ for (int i = 0; i < message_descriptor.field_count(); ++i) {
+ const FieldDescriptor* field_des = message_descriptor.field(i);
if (IsPythonKeyword(field_des->name())) {
continue;
}
@@ -413,48 +430,34 @@ void PyiGenerator::PrintMessage(
}
printer_->Print("]\n");
- std::map<TProtoStringType, TProtoStringType> item_map;
// Prints Extensions for extendable messages
if (message_descriptor.extension_range_count() > 0) {
- item_map["Extensions"] = "_python_message._ExtensionDict";
+ printer_->Print("Extensions: _python_message._ExtensionDict\n");
}
// Prints nested enums
- std::vector<const EnumDescriptor*> nested_enums;
- nested_enums.reserve(message_descriptor.enum_type_count());
for (int i = 0; i < message_descriptor.enum_type_count(); ++i) {
- nested_enums.push_back(message_descriptor.enum_type(i));
- }
- std::sort(nested_enums.begin(), nested_enums.end(),
- SortByName<EnumDescriptor>());
-
- for (const auto& entry : nested_enums) {
- PrintEnum(*entry);
- // Adds enum value to item_map which will be ordered and printed later
- AddEnumValue(*entry, &item_map, import_map);
+ PrintEnum(*message_descriptor.enum_type(i));
+ PrintEnumValues(*message_descriptor.enum_type(i));
}
// Prints nested messages
- std::vector<const Descriptor*> nested_messages;
- nested_messages.reserve(message_descriptor.nested_type_count());
for (int i = 0; i < message_descriptor.nested_type_count(); ++i) {
- nested_messages.push_back(message_descriptor.nested_type(i));
+ PrintMessage(*message_descriptor.nested_type(i), true);
}
- std::sort(nested_messages.begin(), nested_messages.end(),
- SortByName<Descriptor>());
- for (const auto& entry : nested_messages) {
- PrintMessage(*entry, true, import_map);
- }
-
- // Adds extensions to item_map which will be ordered and printed later
- AddExtensions(message_descriptor, &item_map);
+ PrintExtensions(message_descriptor);
- // Adds field number and field descriptor to item_map
+ // Prints field number
+ for (int i = 0; i < message_descriptor.field_count(); ++i) {
+ const FieldDescriptor& field_des = *message_descriptor.field(i);
+ printer_->Print(
+ "$field_number_name$: _ClassVar[int]\n", "field_number_name",
+ y_absl::StrCat(y_absl::AsciiStrToUpper(field_des.name()), "_FIELD_NUMBER"));
+ }
+ // Prints field name and type
for (int i = 0; i < message_descriptor.field_count(); ++i) {
const FieldDescriptor& field_des = *message_descriptor.field(i);
- item_map[ToUpper(field_des.name()) + "_FIELD_NUMBER"] =
- "_ClassVar[int]";
if (IsPythonKeyword(field_des.name())) {
continue;
}
@@ -462,30 +465,29 @@ void PyiGenerator::PrintMessage(
if (field_des.is_map()) {
const FieldDescriptor* key_des = field_des.message_type()->field(0);
const FieldDescriptor* value_des = field_des.message_type()->field(1);
- field_type = (value_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
- ? "_containers.MessageMap["
- : "_containers.ScalarMap[");
- field_type += GetFieldType(*key_des, message_descriptor, import_map);
- field_type += ", ";
- field_type += GetFieldType(*value_des, message_descriptor, import_map);
+ field_type =
+ y_absl::StrCat(value_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
+ ? "_containers.MessageMap["
+ : "_containers.ScalarMap[",
+ GetFieldType(*key_des, message_descriptor), ", ",
+ GetFieldType(*value_des, message_descriptor));
} else {
if (field_des.is_repeated()) {
field_type = (field_des.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
? "_containers.RepeatedCompositeFieldContainer["
: "_containers.RepeatedScalarFieldContainer[");
}
- field_type += GetFieldType(field_des, message_descriptor, import_map);
+ field_type += GetFieldType(field_des, message_descriptor);
}
if (field_des.is_repeated()) {
- field_type += "]";
+ y_absl::StrAppend(&field_type, "]");
}
- item_map[field_des.name()] = field_type;
+ printer_->Print("$name$: $type$\n",
+ "name", field_des.name(), "type", field_type);
+ Annotate("name", &field_des);
}
- // Prints all items in item_map
- PrintItemMap(item_map);
-
// Prints __init__
printer_->Print("def __init__(self");
bool has_key_words = false;
@@ -505,6 +507,7 @@ void PyiGenerator::PrintMessage(
}
is_first = false;
printer_->Print(", $field_name$: ", "field_name", field_name);
+ Annotate("field_name", field_des);
if (field_des->is_repeated() ||
field_des->cpp_type() != FieldDescriptor::CPPTYPE_BOOL) {
printer_->Print("_Optional[");
@@ -513,9 +516,9 @@ void PyiGenerator::PrintMessage(
const Descriptor* map_entry = field_des->message_type();
printer_->Print(
"_Mapping[$key_type$, $value_type$]", "key_type",
- GetFieldType(*map_entry->field(0), message_descriptor, import_map),
+ GetFieldType(*map_entry->field(0), message_descriptor),
"value_type",
- GetFieldType(*map_entry->field(1), message_descriptor, import_map));
+ GetFieldType(*map_entry->field(1), message_descriptor));
} else {
if (field_des->is_repeated()) {
printer_->Print("_Iterable[");
@@ -523,15 +526,15 @@ void PyiGenerator::PrintMessage(
if (field_des->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
printer_->Print(
"_Union[$type_name$, _Mapping]", "type_name",
- GetFieldType(*field_des, message_descriptor, import_map));
+ GetFieldType(*field_des, message_descriptor));
} else {
if (field_des->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
printer_->Print("_Union[$type_name$, str]", "type_name",
- ModuleLevelName(*field_des->enum_type(), import_map));
+ ModuleLevelName(*field_des->enum_type()));
} else {
printer_->Print(
"$type_name$", "type_name",
- GetFieldType(*field_des, message_descriptor, import_map));
+ GetFieldType(*field_des, message_descriptor));
}
}
if (field_des->is_repeated()) {
@@ -548,83 +551,92 @@ void PyiGenerator::PrintMessage(
printer_->Print(", **kwargs");
}
printer_->Print(") -> None: ...\n");
-
- printer_->Outdent();
printer_->Outdent();
}
-void PyiGenerator::PrintMessages(
- const std::map<TProtoStringType, TProtoStringType>& import_map) const {
+void PyiGenerator::PrintMessages() const {
// Deterministically order the descriptors.
- std::vector<const Descriptor*> messages;
- messages.reserve(file_->message_type_count());
for (int i = 0; i < file_->message_type_count(); ++i) {
- messages.push_back(file_->message_type(i));
- }
- std::sort(messages.begin(), messages.end(), SortByName<Descriptor>());
-
- for (const auto& entry : messages) {
- PrintMessage(*entry, false, import_map);
+ PrintMessage(*file_->message_type(i), false);
}
}
void PyiGenerator::PrintServices() const {
- std::vector<const ServiceDescriptor*> services;
- services.reserve(file_->service_count());
- for (int i = 0; i < file_->service_count(); ++i) {
- services.push_back(file_->service(i));
- }
- std::sort(services.begin(), services.end(), SortByName<ServiceDescriptor>());
-
// Prints $Service$ and $Service$_Stub classes
- for (const auto& entry : services) {
+ for (int i = 0; i < file_->service_count(); ++i) {
printer_->Print("\n");
printer_->Print(
"class $service_name$(_service.service): ...\n\n"
"class $service_name$_Stub($service_name$): ...\n",
- "service_name", entry->name());
+ "service_name", file_->service(i)->name());
}
}
+
bool PyiGenerator::Generate(const FileDescriptor* file,
const TProtoStringType& parameter,
GeneratorContext* context,
TProtoStringType* error) const {
- MutexLock lock(&mutex_);
+ y_absl::MutexLock lock(&mutex_);
+ import_map_.clear();
// Calculate file name.
file_ = file;
- TProtoStringType filename =
- parameter.empty() ? GetFileName(file, ".pyi") : parameter;
+ // In google3, devtools/python/blaze/pytype/pytype_impl.bzl uses --pyi_out to
+ // directly set the output file name.
+ std::vector<std::pair<TProtoStringType, TProtoStringType> > options;
+ ParseGeneratorParameter(parameter, &options);
+
+ TProtoStringType filename;
+ bool annotate_code = false;
+ for (const std::pair<TProtoStringType, TProtoStringType>& option : options) {
+ if (option.first == "annotate_code") {
+ annotate_code = true;
+ } else if (y_absl::EndsWith(option.first, ".pyi")) {
+ filename = option.first;
+ } else {
+ *error = y_absl::StrCat("Unknown generator option: ", option.first);
+ return false;
+ }
+ }
+
+ if (filename.empty()) {
+ filename = GetFileName(file, ".pyi");
+ }
std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
- GOOGLE_CHECK(output.get());
- io::Printer printer(output.get(), '$');
+ Y_ABSL_CHECK(output.get());
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ io::Printer::Options printer_opt(
+ '$', annotate_code ? &annotation_collector : nullptr);
+ printer_opt.spaces_per_indent = 4;
+ io::Printer printer(output.get(), printer_opt);
printer_ = &printer;
- // item map will store "DESCRIPTOR", top level extensions, top level enum
- // values. The items will be sorted and printed later.
- std::map<TProtoStringType, TProtoStringType> item_map;
-
- // Adds "DESCRIPTOR" into item_map.
- item_map["DESCRIPTOR"] = "_descriptor.FileDescriptor";
+ PrintImports();
+ printer_->Print("DESCRIPTOR: _descriptor.FileDescriptor\n");
- // import_map will be a mapping from filename to module alias, e.g.
- // "google3/foo/bar.py" -> "_bar"
- std::map<TProtoStringType, TProtoStringType> import_map;
+ // Prints extensions and enums from imports.
+ for (int i = 0; i < file_->public_dependency_count(); ++i) {
+ const FileDescriptor* public_dep = file_->public_dependency(i);
+ PrintExtensions(*public_dep);
+ for (int i = 0; i < public_dep->enum_type_count(); ++i) {
+ const EnumDescriptor* enum_descriptor = public_dep->enum_type(i);
+ PrintEnumValues(*enum_descriptor);
+ }
+ }
- PrintImports(&item_map, &import_map);
- // Adds top level enum values to item_map.
+ PrintTopLevelEnums();
+ // Prints top level enum values
for (int i = 0; i < file_->enum_type_count(); ++i) {
- AddEnumValue(*file_->enum_type(i), &item_map, import_map);
+ PrintEnumValues(*file_->enum_type(i));
}
- // Adds top level extensions to item_map.
- AddExtensions(*file_, &item_map);
- // Prints item map
- PrintItemMap(item_map);
+ // Prints top level Extensions
+ PrintExtensions(*file_);
+ PrintMessages();
- PrintMessages(import_map);
- PrintTopLevelEnums();
- if (HasGenericServices(file)) {
+ if (opensource_runtime_ && HasGenericServices(file)) {
PrintServices();
}
return true;
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/python/pyi_generator.h b/contrib/libs/protoc/src/google/protobuf/compiler/python/pyi_generator.h
index c9bf2961665..091a252c4bd 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/python/pyi_generator.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/python/pyi_generator.h
@@ -35,15 +35,15 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__
-#include <map>
-#include <set>
#include <string>
-#include <google/protobuf/stubs/mutex.h>
-#include <google/protobuf/compiler/code_generator.h>
+#include "y_absl/container/flat_hash_map.h"
+#include "y_absl/container/flat_hash_set.h"
+#include "y_absl/synchronization/mutex.h"
+#include "google/protobuf/compiler/code_generator.h"
// Must be included last.
-#include <google/protobuf/port_def.inc>
+#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
@@ -63,6 +63,8 @@ namespace python {
class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenerator {
public:
PyiGenerator();
+ PyiGenerator(const PyiGenerator&) = delete;
+ PyiGenerator& operator=(const PyiGenerator&) = delete;
~PyiGenerator() override;
// CodeGenerator methods.
@@ -75,39 +77,38 @@ class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenera
TProtoStringType* error) const override;
private:
- void PrintImportForDescriptor(const FileDescriptor& desc,
- std::map<TProtoStringType, TProtoStringType>* import_map,
- std::set<TProtoStringType>* seen_aliases) const;
- void PrintImports(std::map<TProtoStringType, TProtoStringType>* item_map,
- std::map<TProtoStringType, TProtoStringType>* import_map) const;
- void PrintEnum(const EnumDescriptor& enum_descriptor) const;
- void AddEnumValue(const EnumDescriptor& enum_descriptor,
- std::map<TProtoStringType, TProtoStringType>* item_map,
- const std::map<TProtoStringType, TProtoStringType>& import_map) const;
+ void PrintImportForDescriptor(
+ const FileDescriptor& desc,
+ y_absl::flat_hash_set<TProtoStringType>* seen_aliases) const;
+ template <typename DescriptorT>
+ void Annotate(const TProtoStringType& label, const DescriptorT* descriptor) const;
+ void PrintImports() const;
void PrintTopLevelEnums() const;
+ void PrintEnum(const EnumDescriptor& enum_descriptor) const;
+ void PrintEnumValues(const EnumDescriptor& enum_descriptor,
+ bool is_classvar = false) const;
template <typename DescriptorT>
- void AddExtensions(const DescriptorT& descriptor,
- std::map<TProtoStringType, TProtoStringType>* item_map) const;
- void PrintMessages(
- const std::map<TProtoStringType, TProtoStringType>& import_map) const;
- void PrintMessage(const Descriptor& message_descriptor, bool is_nested,
- const std::map<TProtoStringType, TProtoStringType>& import_map) const;
+ void PrintExtensions(const DescriptorT& descriptor) const;
+ void PrintMessages() const;
+ void PrintMessage(const Descriptor& message_descriptor, bool is_nested) const;
void PrintServices() const;
- void PrintItemMap(const std::map<TProtoStringType, TProtoStringType>& item_map) const;
TProtoStringType GetFieldType(
- const FieldDescriptor& field_des, const Descriptor& containing_des,
- const std::map<TProtoStringType, TProtoStringType>& import_map) const;
+ const FieldDescriptor& field_des, const Descriptor& containing_des) const;
template <typename DescriptorT>
- TProtoStringType ModuleLevelName(
- const DescriptorT& descriptor,
- const std::map<TProtoStringType, TProtoStringType>& import_map) const;
+ TProtoStringType ModuleLevelName(const DescriptorT& descriptor) const;
+ TProtoStringType PublicPackage() const;
+ TProtoStringType InternalPackage() const;
+
+ bool opensource_runtime_ = true;
// Very coarse-grained lock to ensure that Generate() is reentrant.
- // Guards file_ and printer_.
- mutable Mutex mutex_;
+ // Guards file_, printer_, and import_map_.
+ mutable y_absl::Mutex mutex_;
mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_.
mutable io::Printer* printer_; // Set in Generate(). Under mutex_.
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PyiGenerator);
+ // import_map will be a mapping from filename to module alias, e.g.
+ // "google3/foo/bar.py" -> "_bar"
+ mutable y_absl::flat_hash_map<TProtoStringType, TProtoStringType> import_map_;
};
} // namespace python
@@ -115,6 +116,6 @@ class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenera
} // namespace protobuf
} // namespace google
-#include <google/protobuf/port_undef.inc>
+#include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__