xref: /aosp_15_r20/external/cronet/third_party/protobuf/src/google/protobuf/compiler/python/generator.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: [email protected] (Will Robinson)
32 //
33 // This module outputs pure-Python protocol message classes that will
34 // largely be constructed at runtime via the metaclass in reflection.py.
35 // In other words, our job is basically to output a Python equivalent
36 // of the C++ *Descriptor objects, and fix up all circular references
37 // within these objects.
38 //
39 // Note that the runtime performance of protocol message classes created in
40 // this way is expected to be lousy.  The plan is to create an alternate
41 // generator that outputs a Python/C extension module that lets
42 // performance-minded Python code leverage the fast C++ implementation
43 // directly.
44 
45 #include <google/protobuf/compiler/python/generator.h>
46 
47 #include <algorithm>
48 #include <limits>
49 #include <map>
50 #include <memory>
51 #include <string>
52 #include <utility>
53 #include <vector>
54 
55 #include <google/protobuf/stubs/logging.h>
56 #include <google/protobuf/stubs/common.h>
57 #include <google/protobuf/stubs/strutil.h>
58 #include <google/protobuf/stubs/stringprintf.h>
59 #include <google/protobuf/stubs/substitute.h>
60 #include <google/protobuf/compiler/python/helpers.h>
61 #include <google/protobuf/compiler/python/pyi_generator.h>
62 #include <google/protobuf/descriptor.h>
63 #include <google/protobuf/descriptor.pb.h>
64 #include <google/protobuf/io/printer.h>
65 #include <google/protobuf/io/zero_copy_stream.h>
66 
67 namespace google {
68 namespace protobuf {
69 namespace compiler {
70 namespace python {
71 
72 namespace {
73 // Returns the alias we assign to the module of the given .proto filename
74 // when importing. See testPackageInitializationImport in
75 // net/proto2/python/internal/reflection_test.py
76 // to see why we need the alias.
ModuleAlias(const std::string & filename)77 std::string ModuleAlias(const std::string& filename) {
78   std::string module_name = ModuleName(filename);
79   // We can't have dots in the module name, so we replace each with _dot_.
80   // But that could lead to a collision between a.b and a_dot_b, so we also
81   // duplicate each underscore.
82   GlobalReplaceSubstring("_", "__", &module_name);
83   GlobalReplaceSubstring(".", "_dot_", &module_name);
84   return module_name;
85 }
86 
87 // Name of the class attribute where we store the Python
88 // descriptor.Descriptor instance for the generated class.
89 // Must stay consistent with the _DESCRIPTOR_KEY constant
90 // in proto2/public/reflection.py.
91 const char kDescriptorKey[] = "DESCRIPTOR";
92 
93 
94 // file output by this generator.
PrintTopBoilerplate(io::Printer * printer,const FileDescriptor * file,bool descriptor_proto)95 void PrintTopBoilerplate(io::Printer* printer, const FileDescriptor* file,
96                          bool descriptor_proto) {
97   // TODO(robinson): Allow parameterization of Python version?
98   printer->Print(
99       "# -*- coding: utf-8 -*-\n"
100       "# Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
101       "# source: $filename$\n"
102       "\"\"\"Generated protocol buffer code.\"\"\"\n",
103       "filename", file->name());
104   printer->Print(
105       "from google.protobuf.internal import builder as _builder\n"
106       "from google.protobuf import descriptor as _descriptor\n"
107       "from google.protobuf import descriptor_pool as "
108       "_descriptor_pool\n"
109       "from google.protobuf import symbol_database as "
110       "_symbol_database\n");
111 
112   printer->Print("# @@protoc_insertion_point(imports)\n\n");
113   printer->Print("_sym_db = _symbol_database.Default()\n");
114   printer->Print("\n\n");
115 }
116 
117 // Returns a Python literal giving the default value for a field.
118 // If the field specifies no explicit default value, we'll return
119 // the default default value for the field type (zero for numbers,
120 // empty string for strings, empty list for repeated fields, and
121 // None for non-repeated, composite fields).
122 //
123 // TODO(robinson): Unify with code from
124 // //compiler/cpp/internal/primitive_field.cc
125 // //compiler/cpp/internal/enum_field.cc
126 // //compiler/cpp/internal/string_field.cc
StringifyDefaultValue(const FieldDescriptor & field)127 std::string StringifyDefaultValue(const FieldDescriptor& field) {
128   if (field.is_repeated()) {
129     return "[]";
130   }
131 
132   switch (field.cpp_type()) {
133     case FieldDescriptor::CPPTYPE_INT32:
134       return StrCat(field.default_value_int32());
135     case FieldDescriptor::CPPTYPE_UINT32:
136       return StrCat(field.default_value_uint32());
137     case FieldDescriptor::CPPTYPE_INT64:
138       return StrCat(field.default_value_int64());
139     case FieldDescriptor::CPPTYPE_UINT64:
140       return StrCat(field.default_value_uint64());
141     case FieldDescriptor::CPPTYPE_DOUBLE: {
142       double value = field.default_value_double();
143       if (value == std::numeric_limits<double>::infinity()) {
144         // Python pre-2.6 on Windows does not parse "inf" correctly.  However,
145         // a numeric literal that is too big for a double will become infinity.
146         return "1e10000";
147       } else if (value == -std::numeric_limits<double>::infinity()) {
148         // See above.
149         return "-1e10000";
150       } else if (value != value) {
151         // infinity * 0 = nan
152         return "(1e10000 * 0)";
153       } else {
154         return "float(" + SimpleDtoa(value) + ")";
155       }
156     }
157     case FieldDescriptor::CPPTYPE_FLOAT: {
158       float value = field.default_value_float();
159       if (value == std::numeric_limits<float>::infinity()) {
160         // Python pre-2.6 on Windows does not parse "inf" correctly.  However,
161         // a numeric literal that is too big for a double will become infinity.
162         return "1e10000";
163       } else if (value == -std::numeric_limits<float>::infinity()) {
164         // See above.
165         return "-1e10000";
166       } else if (value != value) {
167         // infinity - infinity = nan
168         return "(1e10000 * 0)";
169       } else {
170         return "float(" + SimpleFtoa(value) + ")";
171       }
172     }
173     case FieldDescriptor::CPPTYPE_BOOL:
174       return field.default_value_bool() ? "True" : "False";
175     case FieldDescriptor::CPPTYPE_ENUM:
176       return StrCat(field.default_value_enum()->number());
177     case FieldDescriptor::CPPTYPE_STRING:
178       return "b\"" + CEscape(field.default_value_string()) +
179              (field.type() != FieldDescriptor::TYPE_STRING
180                   ? "\""
181                   : "\".decode('utf-8')");
182     case FieldDescriptor::CPPTYPE_MESSAGE:
183       return "None";
184   }
185   // (We could add a default case above but then we wouldn't get the nice
186   // compiler warning when a new type is added.)
187   GOOGLE_LOG(FATAL) << "Not reached.";
188   return "";
189 }
190 
StringifySyntax(FileDescriptor::Syntax syntax)191 std::string StringifySyntax(FileDescriptor::Syntax syntax) {
192   switch (syntax) {
193     case FileDescriptor::SYNTAX_PROTO2:
194       return "proto2";
195     case FileDescriptor::SYNTAX_PROTO3:
196       return "proto3";
197     case FileDescriptor::SYNTAX_UNKNOWN:
198     default:
199       GOOGLE_LOG(FATAL) << "Unsupported syntax; this generator only supports proto2 "
200                     "and proto3 syntax.";
201       return "";
202   }
203 }
204 
205 }  // namespace
206 
Generator()207 Generator::Generator() : file_(nullptr) {}
208 
~Generator()209 Generator::~Generator() {}
210 
GetSupportedFeatures() const211 uint64_t Generator::GetSupportedFeatures() const {
212   return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL;
213 }
214 
Generate(const FileDescriptor * file,const std::string & parameter,GeneratorContext * context,std::string * error) const215 bool Generator::Generate(const FileDescriptor* file,
216                          const std::string& parameter,
217                          GeneratorContext* context, std::string* error) const {
218   // -----------------------------------------------------------------
219   // parse generator options
220   bool cpp_generated_lib_linked = false;
221 
222   std::vector<std::pair<std::string, std::string> > options;
223   ParseGeneratorParameter(parameter, &options);
224 
225   for (int i = 0; i < options.size(); i++) {
226     if (options[i].first == "cpp_generated_lib_linked") {
227       cpp_generated_lib_linked = true;
228     } else if (options[i].first == "pyi_out") {
229       python::PyiGenerator pyi_generator;
230       if (!pyi_generator.Generate(file, "", context, error)) {
231         return false;
232       }
233     } else {
234       *error = "Unknown generator option: " + options[i].first;
235       return false;
236     }
237   }
238 
239   // Completely serialize all Generate() calls on this instance.  The
240   // thread-safety constraints of the CodeGenerator interface aren't clear so
241   // just be as conservative as possible.  It's easier to relax this later if
242   // we need to, but I doubt it will be an issue.
243   // TODO(kenton):  The proper thing to do would be to allocate any state on
244   //   the stack and use that, so that the Generator class itself does not need
245   //   to have any mutable members.  Then it is implicitly thread-safe.
246   MutexLock lock(&mutex_);
247   file_ = file;
248 
249   std::string filename = GetFileName(file, ".py");
250   pure_python_workable_ = !cpp_generated_lib_linked;
251   if (HasPrefixString(file->name(), "google/protobuf/")) {
252     pure_python_workable_ = true;
253   }
254 
255   FileDescriptorProto fdp;
256   file_->CopyTo(&fdp);
257   fdp.SerializeToString(&file_descriptor_serialized_);
258 
259 
260   std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
261   GOOGLE_CHECK(output.get());
262   io::Printer printer(output.get(), '$');
263   printer_ = &printer;
264 
265   PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
266   if (pure_python_workable_) {
267     PrintImports();
268   }
269   PrintFileDescriptor();
270   if (pure_python_workable_) {
271     if (GeneratingDescriptorProto()) {
272       printer_->Print("if _descriptor._USE_C_DESCRIPTORS == False:\n");
273       printer_->Indent();
274       // Create enums before message descriptors
275       PrintAllNestedEnumsInFile();
276       PrintMessageDescriptors();
277       FixForeignFieldsInDescriptors();
278       printer_->Outdent();
279       printer_->Print("else:\n");
280       printer_->Indent();
281     }
282     // Find the message descriptors first and then use the message
283     // descriptor to find enums.
284     printer_->Print(
285         "_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())\n");
286     if (GeneratingDescriptorProto()) {
287       printer_->Outdent();
288     }
289   }
290   std::string module_name = ModuleName(file->name());
291   printer_->Print(
292       "_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, '$module_name$', "
293       "globals())\n",
294       "module_name", module_name);
295   if (pure_python_workable_) {
296     printer.Print("if _descriptor._USE_C_DESCRIPTORS == False:\n");
297     printer_->Indent();
298 
299     // We have to fix up the extensions after the message classes themselves,
300     // since they need to call static RegisterExtension() methods on these
301     // classes.
302     FixForeignFieldsInExtensions();
303     // Descriptor options may have custom extensions. These custom options
304     // can only be successfully parsed after we register corresponding
305     // extensions. Therefore we parse all options again here to recognize
306     // custom options that may be unknown when we define the descriptors.
307     // This does not apply to services because they are not used by extensions.
308     FixAllDescriptorOptions();
309 
310     // Set serialized_start and serialized_end.
311     SetSerializedPbInterval();
312 
313     printer_->Outdent();
314   }
315   if (HasGenericServices(file)) {
316     printer_->Print(
317         "_builder.BuildServices(DESCRIPTOR, '$module_name$', globals())\n",
318         "module_name", module_name);
319   }
320 
321   printer.Print("# @@protoc_insertion_point(module_scope)\n");
322 
323   return !printer.failed();
324 }
325 
326 // Prints Python imports for all modules imported by |file|.
PrintImports() const327 void Generator::PrintImports() const {
328   for (int i = 0; i < file_->dependency_count(); ++i) {
329     const std::string& filename = file_->dependency(i)->name();
330 
331     std::string module_name = ModuleName(filename);
332     std::string module_alias = ModuleAlias(filename);
333     if (ContainsPythonKeyword(module_name)) {
334       // If the module path contains a Python keyword, we have to quote the
335       // module name and import it using importlib. Otherwise the usual kind of
336       // import statement would result in a syntax error from the presence of
337       // the keyword.
338       printer_->Print("import importlib\n");
339       printer_->Print("$alias$ = importlib.import_module('$name$')\n", "alias",
340                       module_alias, "name", module_name);
341     } else {
342       int last_dot_pos = module_name.rfind('.');
343       std::string import_statement;
344       if (last_dot_pos == std::string::npos) {
345         // NOTE(petya): this is not tested as it would require a protocol buffer
346         // outside of any package, and I don't think that is easily achievable.
347         import_statement = "import " + module_name;
348       } else {
349         import_statement = "from " + module_name.substr(0, last_dot_pos) +
350                            " import " + module_name.substr(last_dot_pos + 1);
351       }
352       printer_->Print("$statement$ as $alias$\n", "statement", import_statement,
353                       "alias", module_alias);
354     }
355 
356     CopyPublicDependenciesAliases(module_alias, file_->dependency(i));
357   }
358   printer_->Print("\n");
359 
360   // Print public imports.
361   for (int i = 0; i < file_->public_dependency_count(); ++i) {
362     std::string module_name = ModuleName(file_->public_dependency(i)->name());
363     printer_->Print("from $module$ import *\n", "module", module_name);
364   }
365   printer_->Print("\n");
366 }
367 
368 // Prints the single file descriptor for this file.
PrintFileDescriptor() const369 void Generator::PrintFileDescriptor() const {
370   std::map<std::string, std::string> m;
371   m["descriptor_name"] = kDescriptorKey;
372   m["name"] = file_->name();
373   m["package"] = file_->package();
374   m["syntax"] = StringifySyntax(file_->syntax());
375   m["options"] = OptionsValue(file_->options().SerializeAsString());
376   m["serialized_descriptor"] = strings::CHexEscape(file_descriptor_serialized_);
377   if (GeneratingDescriptorProto()) {
378     printer_->Print("if _descriptor._USE_C_DESCRIPTORS == False:\n");
379     printer_->Indent();
380     // Pure python's AddSerializedFile() depend on the generated
381     // descriptor_pb2.py thus we can not use AddSerializedFile() when
382     // generated descriptor.proto for pure python.
383     const char file_descriptor_template[] =
384         "$descriptor_name$ = _descriptor.FileDescriptor(\n"
385         "  name='$name$',\n"
386         "  package='$package$',\n"
387         "  syntax='$syntax$',\n"
388         "  serialized_options=$options$,\n"
389         "  create_key=_descriptor._internal_create_key,\n";
390     printer_->Print(m, file_descriptor_template);
391     printer_->Indent();
392     if (pure_python_workable_) {
393       printer_->Print("serialized_pb=b'$value$'\n", "value",
394                       strings::CHexEscape(file_descriptor_serialized_));
395       if (file_->dependency_count() != 0) {
396         printer_->Print(",\ndependencies=[");
397         for (int i = 0; i < file_->dependency_count(); ++i) {
398           std::string module_alias = ModuleAlias(file_->dependency(i)->name());
399           printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
400                           module_alias);
401         }
402         printer_->Print("]");
403       }
404       if (file_->public_dependency_count() > 0) {
405         printer_->Print(",\npublic_dependencies=[");
406         for (int i = 0; i < file_->public_dependency_count(); ++i) {
407           std::string module_alias =
408               ModuleAlias(file_->public_dependency(i)->name());
409           printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
410                           module_alias);
411         }
412         printer_->Print("]");
413       }
414     } else {
415       printer_->Print("serialized_pb=''\n");
416     }
417 
418     // TODO(falk): Also print options and fix the message_type, enum_type,
419     //             service and extension later in the generation.
420 
421     printer_->Outdent();
422     printer_->Print(")\n");
423 
424     printer_->Outdent();
425     printer_->Print("else:\n");
426     printer_->Indent();
427   }
428   printer_->Print(m,
429                   "$descriptor_name$ = "
430                   "_descriptor_pool.Default().AddSerializedFile(b'$serialized_"
431                   "descriptor$')\n");
432   if (GeneratingDescriptorProto()) {
433     printer_->Outdent();
434   }
435   printer_->Print("\n");
436 }
437 
438 // Prints all enums contained in all message types in |file|.
PrintAllNestedEnumsInFile() const439 void Generator::PrintAllNestedEnumsInFile() const {
440   for (int i = 0; i < file_->message_type_count(); ++i) {
441     PrintNestedEnums(*file_->message_type(i));
442   }
443 }
444 
445 // Prints a Python statement assigning the appropriate module-level
446 // enum name to a Python EnumDescriptor object equivalent to
447 // enum_descriptor.
PrintEnum(const EnumDescriptor & enum_descriptor) const448 void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
449   std::map<std::string, std::string> m;
450   std::string module_level_descriptor_name =
451       ModuleLevelDescriptorName(enum_descriptor);
452   m["descriptor_name"] = module_level_descriptor_name;
453   m["name"] = enum_descriptor.name();
454   m["full_name"] = enum_descriptor.full_name();
455   m["file"] = kDescriptorKey;
456   const char enum_descriptor_template[] =
457       "$descriptor_name$ = _descriptor.EnumDescriptor(\n"
458       "  name='$name$',\n"
459       "  full_name='$full_name$',\n"
460       "  filename=None,\n"
461       "  file=$file$,\n"
462       "  create_key=_descriptor._internal_create_key,\n"
463       "  values=[\n";
464   std::string options_string;
465   enum_descriptor.options().SerializeToString(&options_string);
466   printer_->Print(m, enum_descriptor_template);
467   printer_->Indent();
468   printer_->Indent();
469 
470   if (pure_python_workable_) {
471     for (int i = 0; i < enum_descriptor.value_count(); ++i) {
472       PrintEnumValueDescriptor(*enum_descriptor.value(i));
473       printer_->Print(",\n");
474     }
475   }
476 
477   printer_->Outdent();
478   printer_->Print("],\n");
479   printer_->Print("containing_type=None,\n");
480   printer_->Print("serialized_options=$options_value$,\n", "options_value",
481                   OptionsValue(options_string));
482   EnumDescriptorProto edp;
483   printer_->Outdent();
484   printer_->Print(")\n");
485   if (pure_python_workable_) {
486     printer_->Print("_sym_db.RegisterEnumDescriptor($name$)\n", "name",
487                     module_level_descriptor_name);
488   }
489   printer_->Print("\n");
490 }
491 
492 // Recursively prints enums in nested types within descriptor, then
493 // prints enums contained at the top level in descriptor.
PrintNestedEnums(const Descriptor & descriptor) const494 void Generator::PrintNestedEnums(const Descriptor& descriptor) const {
495   for (int i = 0; i < descriptor.nested_type_count(); ++i) {
496     PrintNestedEnums(*descriptor.nested_type(i));
497   }
498 
499   for (int i = 0; i < descriptor.enum_type_count(); ++i) {
500     PrintEnum(*descriptor.enum_type(i));
501   }
502 }
503 
504 // Prints Python equivalents of all Descriptors in |file|.
PrintMessageDescriptors() const505 void Generator::PrintMessageDescriptors() const {
506   for (int i = 0; i < file_->message_type_count(); ++i) {
507     PrintDescriptor(*file_->message_type(i));
508     printer_->Print("\n");
509   }
510 }
511 
PrintServiceDescriptors() const512 void Generator::PrintServiceDescriptors() const {
513   for (int i = 0; i < file_->service_count(); ++i) {
514     PrintServiceDescriptor(*file_->service(i));
515   }
516 }
517 
PrintServices() const518 void Generator::PrintServices() const {
519   for (int i = 0; i < file_->service_count(); ++i) {
520     PrintServiceClass(*file_->service(i));
521     PrintServiceStub(*file_->service(i));
522     printer_->Print("\n");
523   }
524 }
525 
PrintServiceDescriptor(const ServiceDescriptor & descriptor) const526 void Generator::PrintServiceDescriptor(
527     const ServiceDescriptor& descriptor) const {
528   std::map<std::string, std::string> m;
529   m["service_name"] = ModuleLevelServiceDescriptorName(descriptor);
530   m["name"] = descriptor.name();
531   m["file"] = kDescriptorKey;
532   printer_->Print(m, "$service_name$ = $file$.services_by_name['$name$']\n");
533 }
534 
PrintDescriptorKeyAndModuleName(const ServiceDescriptor & descriptor) const535 void Generator::PrintDescriptorKeyAndModuleName(
536     const ServiceDescriptor& descriptor) const {
537   std::string name = ModuleLevelServiceDescriptorName(descriptor);
538   if (!pure_python_workable_) {
539     name = "_descriptor.ServiceDescriptor(full_name='" +
540            descriptor.full_name() + "')";
541   }
542   printer_->Print("$descriptor_key$ = $descriptor_name$,\n", "descriptor_key",
543                   kDescriptorKey, "descriptor_name", name);
544   std::string module_name = ModuleName(file_->name());
545   printer_->Print("__module__ = '$module_name$'\n", "module_name", module_name);
546 }
547 
PrintServiceClass(const ServiceDescriptor & descriptor) const548 void Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const {
549   // Print the service.
550   printer_->Print(
551       "$class_name$ = service_reflection.GeneratedServiceType("
552       "'$class_name$', (_service.Service,), dict(\n",
553       "class_name", descriptor.name());
554   printer_->Indent();
555   Generator::PrintDescriptorKeyAndModuleName(descriptor);
556   printer_->Print("))\n\n");
557   printer_->Outdent();
558 }
559 
PrintServiceStub(const ServiceDescriptor & descriptor) const560 void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const {
561   // Print the service stub.
562   printer_->Print(
563       "$class_name$_Stub = "
564       "service_reflection.GeneratedServiceStubType("
565       "'$class_name$_Stub', ($class_name$,), dict(\n",
566       "class_name", descriptor.name());
567   printer_->Indent();
568   Generator::PrintDescriptorKeyAndModuleName(descriptor);
569   printer_->Print("))\n\n");
570   printer_->Outdent();
571 }
572 
573 // Prints statement assigning ModuleLevelDescriptorName(message_descriptor)
574 // to a Python Descriptor object for message_descriptor.
575 //
576 // Mutually recursive with PrintNestedDescriptors().
PrintDescriptor(const Descriptor & message_descriptor) const577 void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
578   std::map<std::string, std::string> m;
579   m["name"] = message_descriptor.name();
580   m["full_name"] = message_descriptor.full_name();
581   m["file"] = kDescriptorKey;
582 
583   PrintNestedDescriptors(message_descriptor);
584 
585   printer_->Print("\n");
586   printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n",
587                   "descriptor_name",
588                   ModuleLevelDescriptorName(message_descriptor));
589   printer_->Indent();
590   const char required_function_arguments[] =
591       "name='$name$',\n"
592       "full_name='$full_name$',\n"
593       "filename=None,\n"
594       "file=$file$,\n"
595       "containing_type=None,\n"
596       "create_key=_descriptor._internal_create_key,\n";
597   printer_->Print(m, required_function_arguments);
598   PrintFieldsInDescriptor(message_descriptor);
599   PrintExtensionsInDescriptor(message_descriptor);
600 
601   // Nested types
602   printer_->Print("nested_types=[");
603   for (int i = 0; i < message_descriptor.nested_type_count(); ++i) {
604     const std::string nested_name =
605         ModuleLevelDescriptorName(*message_descriptor.nested_type(i));
606     printer_->Print("$name$, ", "name", nested_name);
607   }
608   printer_->Print("],\n");
609 
610   // Enum types
611   printer_->Print("enum_types=[\n");
612   printer_->Indent();
613   for (int i = 0; i < message_descriptor.enum_type_count(); ++i) {
614     const std::string descriptor_name =
615         ModuleLevelDescriptorName(*message_descriptor.enum_type(i));
616     printer_->Print(descriptor_name.c_str());
617     printer_->Print(",\n");
618   }
619   printer_->Outdent();
620   printer_->Print("],\n");
621   std::string options_string;
622   message_descriptor.options().SerializeToString(&options_string);
623   printer_->Print(
624       "serialized_options=$options_value$,\n"
625       "is_extendable=$extendable$,\n"
626       "syntax='$syntax$'",
627       "options_value", OptionsValue(options_string), "extendable",
628       message_descriptor.extension_range_count() > 0 ? "True" : "False",
629       "syntax", StringifySyntax(message_descriptor.file()->syntax()));
630   printer_->Print(",\n");
631 
632   // Extension ranges
633   printer_->Print("extension_ranges=[");
634   for (int i = 0; i < message_descriptor.extension_range_count(); ++i) {
635     const Descriptor::ExtensionRange* range =
636         message_descriptor.extension_range(i);
637     printer_->Print("($start$, $end$), ", "start", StrCat(range->start),
638                     "end", StrCat(range->end));
639   }
640   printer_->Print("],\n");
641   printer_->Print("oneofs=[\n");
642   printer_->Indent();
643   for (int i = 0; i < message_descriptor.oneof_decl_count(); ++i) {
644     const OneofDescriptor* desc = message_descriptor.oneof_decl(i);
645     m.clear();
646     m["name"] = desc->name();
647     m["full_name"] = desc->full_name();
648     m["index"] = StrCat(desc->index());
649     options_string = OptionsValue(desc->options().SerializeAsString());
650     if (options_string == "None") {
651       m["serialized_options"] = "";
652     } else {
653       m["serialized_options"] = ", serialized_options=" + options_string;
654     }
655     printer_->Print(m,
656                     "_descriptor.OneofDescriptor(\n"
657                     "  name='$name$', full_name='$full_name$',\n"
658                     "  index=$index$, containing_type=None,\n"
659                     "  create_key=_descriptor._internal_create_key,\n"
660                     "fields=[]$serialized_options$),\n");
661   }
662   printer_->Outdent();
663   printer_->Print("],\n");
664 
665   printer_->Outdent();
666   printer_->Print(")\n");
667 }
668 
669 // Prints Python Descriptor objects for all nested types contained in
670 // message_descriptor.
671 //
672 // Mutually recursive with PrintDescriptor().
PrintNestedDescriptors(const Descriptor & containing_descriptor) const673 void Generator::PrintNestedDescriptors(
674     const Descriptor& containing_descriptor) const {
675   for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
676     PrintDescriptor(*containing_descriptor.nested_type(i));
677   }
678 }
679 
680 // Prints all messages in |file|.
PrintMessages() const681 void Generator::PrintMessages() const {
682   for (int i = 0; i < file_->message_type_count(); ++i) {
683     std::vector<std::string> to_register;
684     PrintMessage(*file_->message_type(i), "", &to_register, false);
685     for (int j = 0; j < to_register.size(); ++j) {
686       printer_->Print("_sym_db.RegisterMessage($name$)\n", "name",
687                       ResolveKeyword(to_register[j]));
688     }
689     printer_->Print("\n");
690   }
691 }
692 
693 // Prints a Python class for the given message descriptor.  We defer to the
694 // metaclass to do almost all of the work of actually creating a useful class.
695 // The purpose of this function and its many helper functions above is merely
696 // to output a Python version of the descriptors, which the metaclass in
697 // reflection.py will use to construct the meat of the class itself.
698 //
699 // Mutually recursive with PrintNestedMessages().
700 // Collect nested message names to_register for the symbol_database.
PrintMessage(const Descriptor & message_descriptor,const std::string & prefix,std::vector<std::string> * to_register,bool is_nested) const701 void Generator::PrintMessage(const Descriptor& message_descriptor,
702                              const std::string& prefix,
703                              std::vector<std::string>* to_register,
704                              bool is_nested) const {
705   std::string qualified_name;
706   if (is_nested) {
707     if (IsPythonKeyword(message_descriptor.name())) {
708       qualified_name =
709           "getattr(" + prefix + ", '" + message_descriptor.name() + "')";
710     } else {
711       qualified_name = prefix + "." + message_descriptor.name();
712     }
713     printer_->Print(
714         "'$name$' : _reflection.GeneratedProtocolMessageType('$name$', "
715         "(_message.Message,), {\n",
716         "name", message_descriptor.name());
717   } else {
718     qualified_name = ResolveKeyword(message_descriptor.name());
719     printer_->Print(
720         "$qualified_name$ = _reflection.GeneratedProtocolMessageType('$name$', "
721         "(_message.Message,), {\n",
722         "qualified_name", qualified_name, "name", message_descriptor.name());
723   }
724   printer_->Indent();
725 
726   to_register->push_back(qualified_name);
727 
728   PrintNestedMessages(message_descriptor, qualified_name, to_register);
729   std::map<std::string, std::string> m;
730   m["descriptor_key"] = kDescriptorKey;
731   if (pure_python_workable_) {
732     m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
733   } else {
734     m["descriptor_name"] = "_descriptor.Descriptor(full_name='" +
735                            message_descriptor.full_name() + "')";
736   }
737   printer_->Print(m, "'$descriptor_key$' : $descriptor_name$,\n");
738   std::string module_name = ModuleName(file_->name());
739   printer_->Print("'__module__' : '$module_name$'\n", "module_name",
740                   module_name);
741   printer_->Print("# @@protoc_insertion_point(class_scope:$full_name$)\n",
742                   "full_name", message_descriptor.full_name());
743   printer_->Print("})\n");
744   printer_->Outdent();
745 }
746 
747 // Prints all nested messages within |containing_descriptor|.
748 // Mutually recursive with PrintMessage().
PrintNestedMessages(const Descriptor & containing_descriptor,const std::string & prefix,std::vector<std::string> * to_register) const749 void Generator::PrintNestedMessages(
750     const Descriptor& containing_descriptor, const std::string& prefix,
751     std::vector<std::string>* to_register) const {
752   for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
753     printer_->Print("\n");
754     PrintMessage(*containing_descriptor.nested_type(i), prefix, to_register,
755                  true);
756     printer_->Print(",\n");
757   }
758 }
759 
760 // Recursively fixes foreign fields in all nested types in |descriptor|, then
761 // sets the message_type and enum_type of all message and enum fields to point
762 // to their respective descriptors.
763 // Args:
764 //   descriptor: descriptor to print fields for.
765 //   containing_descriptor: if descriptor is a nested type, this is its
766 //       containing type, or NULL if this is a root/top-level type.
FixForeignFieldsInDescriptor(const Descriptor & descriptor,const Descriptor * containing_descriptor) const767 void Generator::FixForeignFieldsInDescriptor(
768     const Descriptor& descriptor,
769     const Descriptor* containing_descriptor) const {
770   for (int i = 0; i < descriptor.nested_type_count(); ++i) {
771     FixForeignFieldsInDescriptor(*descriptor.nested_type(i), &descriptor);
772   }
773 
774   for (int i = 0; i < descriptor.field_count(); ++i) {
775     const FieldDescriptor& field_descriptor = *descriptor.field(i);
776     FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name");
777   }
778 
779   FixContainingTypeInDescriptor(descriptor, containing_descriptor);
780   for (int i = 0; i < descriptor.enum_type_count(); ++i) {
781     const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i);
782     FixContainingTypeInDescriptor(enum_descriptor, &descriptor);
783   }
784   for (int i = 0; i < descriptor.oneof_decl_count(); ++i) {
785     std::map<std::string, std::string> m;
786     const OneofDescriptor* oneof = descriptor.oneof_decl(i);
787     m["descriptor_name"] = ModuleLevelDescriptorName(descriptor);
788     m["oneof_name"] = oneof->name();
789     for (int j = 0; j < oneof->field_count(); ++j) {
790       m["field_name"] = oneof->field(j)->name();
791       printer_->Print(
792           m,
793           "$descriptor_name$.oneofs_by_name['$oneof_name$'].fields.append(\n"
794           "  $descriptor_name$.fields_by_name['$field_name$'])\n");
795       printer_->Print(
796           m,
797           "$descriptor_name$.fields_by_name['$field_name$'].containing_oneof = "
798           "$descriptor_name$.oneofs_by_name['$oneof_name$']\n");
799     }
800   }
801 }
802 
AddMessageToFileDescriptor(const Descriptor & descriptor) const803 void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const {
804   std::map<std::string, std::string> m;
805   m["descriptor_name"] = kDescriptorKey;
806   m["message_name"] = descriptor.name();
807   m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
808   const char file_descriptor_template[] =
809       "$descriptor_name$.message_types_by_name['$message_name$'] = "
810       "$message_descriptor_name$\n";
811   printer_->Print(m, file_descriptor_template);
812 }
813 
AddServiceToFileDescriptor(const ServiceDescriptor & descriptor) const814 void Generator::AddServiceToFileDescriptor(
815     const ServiceDescriptor& descriptor) const {
816   std::map<std::string, std::string> m;
817   m["descriptor_name"] = kDescriptorKey;
818   m["service_name"] = descriptor.name();
819   m["service_descriptor_name"] = ModuleLevelServiceDescriptorName(descriptor);
820   const char file_descriptor_template[] =
821       "$descriptor_name$.services_by_name['$service_name$'] = "
822       "$service_descriptor_name$\n";
823   printer_->Print(m, file_descriptor_template);
824 }
825 
AddEnumToFileDescriptor(const EnumDescriptor & descriptor) const826 void Generator::AddEnumToFileDescriptor(
827     const EnumDescriptor& descriptor) const {
828   std::map<std::string, std::string> m;
829   m["descriptor_name"] = kDescriptorKey;
830   m["enum_name"] = descriptor.name();
831   m["enum_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
832   const char file_descriptor_template[] =
833       "$descriptor_name$.enum_types_by_name['$enum_name$'] = "
834       "$enum_descriptor_name$\n";
835   printer_->Print(m, file_descriptor_template);
836 }
837 
AddExtensionToFileDescriptor(const FieldDescriptor & descriptor) const838 void Generator::AddExtensionToFileDescriptor(
839     const FieldDescriptor& descriptor) const {
840   std::map<std::string, std::string> m;
841   m["descriptor_name"] = kDescriptorKey;
842   m["field_name"] = descriptor.name();
843   m["resolved_name"] = ResolveKeyword(descriptor.name());
844   const char file_descriptor_template[] =
845       "$descriptor_name$.extensions_by_name['$field_name$'] = "
846       "$resolved_name$\n";
847   printer_->Print(m, file_descriptor_template);
848 }
849 
850 // Sets any necessary message_type and enum_type attributes
851 // for the Python version of |field|.
852 //
853 // containing_type may be NULL, in which case this is a module-level field.
854 //
855 // python_dict_name is the name of the Python dict where we should
856 // look the field up in the containing type.  (e.g., fields_by_name
857 // or extensions_by_name).  We ignore python_dict_name if containing_type
858 // is NULL.
FixForeignFieldsInField(const Descriptor * containing_type,const FieldDescriptor & field,const std::string & python_dict_name) const859 void Generator::FixForeignFieldsInField(
860     const Descriptor* containing_type, const FieldDescriptor& field,
861     const std::string& python_dict_name) const {
862   const std::string field_referencing_expression =
863       FieldReferencingExpression(containing_type, field, python_dict_name);
864   std::map<std::string, std::string> m;
865   m["field_ref"] = field_referencing_expression;
866   const Descriptor* foreign_message_type = field.message_type();
867   if (foreign_message_type) {
868     m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type);
869     printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n");
870   }
871   const EnumDescriptor* enum_type = field.enum_type();
872   if (enum_type) {
873     m["enum_type"] = ModuleLevelDescriptorName(*enum_type);
874     printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n");
875   }
876 }
877 
878 // Returns the module-level expression for the given FieldDescriptor.
879 // Only works for fields in the .proto file this Generator is generating for.
880 //
881 // containing_type may be NULL, in which case this is a module-level field.
882 //
883 // python_dict_name is the name of the Python dict where we should
884 // look the field up in the containing type.  (e.g., fields_by_name
885 // or extensions_by_name).  We ignore python_dict_name if containing_type
886 // is NULL.
FieldReferencingExpression(const Descriptor * containing_type,const FieldDescriptor & field,const std::string & python_dict_name) const887 std::string Generator::FieldReferencingExpression(
888     const Descriptor* containing_type, const FieldDescriptor& field,
889     const std::string& python_dict_name) const {
890   // We should only ever be looking up fields in the current file.
891   // The only things we refer to from other files are message descriptors.
892   GOOGLE_CHECK_EQ(field.file(), file_)
893       << field.file()->name() << " vs. " << file_->name();
894   if (!containing_type) {
895     return ResolveKeyword(field.name());
896   }
897   return strings::Substitute("$0.$1['$2']",
898                           ModuleLevelDescriptorName(*containing_type),
899                           python_dict_name, field.name());
900 }
901 
902 // Prints containing_type for nested descriptors or enum descriptors.
903 template <typename DescriptorT>
FixContainingTypeInDescriptor(const DescriptorT & descriptor,const Descriptor * containing_descriptor) const904 void Generator::FixContainingTypeInDescriptor(
905     const DescriptorT& descriptor,
906     const Descriptor* containing_descriptor) const {
907   if (containing_descriptor != nullptr) {
908     const std::string nested_name = ModuleLevelDescriptorName(descriptor);
909     const std::string parent_name =
910         ModuleLevelDescriptorName(*containing_descriptor);
911     printer_->Print("$nested_name$.containing_type = $parent_name$\n",
912                     "nested_name", nested_name, "parent_name", parent_name);
913   }
914 }
915 
916 // Prints statements setting the message_type and enum_type fields in the
917 // Python descriptor objects we've already output in the file.  We must
918 // do this in a separate step due to circular references (otherwise, we'd
919 // just set everything in the initial assignment statements).
FixForeignFieldsInDescriptors() const920 void Generator::FixForeignFieldsInDescriptors() const {
921   for (int i = 0; i < file_->message_type_count(); ++i) {
922     FixForeignFieldsInDescriptor(*file_->message_type(i), nullptr);
923   }
924   for (int i = 0; i < file_->message_type_count(); ++i) {
925     AddMessageToFileDescriptor(*file_->message_type(i));
926   }
927   for (int i = 0; i < file_->enum_type_count(); ++i) {
928     AddEnumToFileDescriptor(*file_->enum_type(i));
929   }
930   for (int i = 0; i < file_->extension_count(); ++i) {
931     AddExtensionToFileDescriptor(*file_->extension(i));
932   }
933 
934   // TODO(jieluo): Move this register to PrintFileDescriptor() when
935   // FieldDescriptor.file is added in generated file.
936   printer_->Print("_sym_db.RegisterFileDescriptor($name$)\n", "name",
937                   kDescriptorKey);
938   printer_->Print("\n");
939 }
940 
941 // We need to not only set any necessary message_type fields, but
942 // also need to call RegisterExtension() on each message we're
943 // extending.
FixForeignFieldsInExtensions() const944 void Generator::FixForeignFieldsInExtensions() const {
945   // Top-level extensions.
946   for (int i = 0; i < file_->extension_count(); ++i) {
947     FixForeignFieldsInExtension(*file_->extension(i));
948   }
949   // Nested extensions.
950   for (int i = 0; i < file_->message_type_count(); ++i) {
951     FixForeignFieldsInNestedExtensions(*file_->message_type(i));
952   }
953   printer_->Print("\n");
954 }
955 
FixForeignFieldsInExtension(const FieldDescriptor & extension_field) const956 void Generator::FixForeignFieldsInExtension(
957     const FieldDescriptor& extension_field) const {
958   GOOGLE_CHECK(extension_field.is_extension());
959 
960   std::map<std::string, std::string> m;
961   // Confusingly, for FieldDescriptors that happen to be extensions,
962   // containing_type() means "extended type."
963   // On the other hand, extension_scope() will give us what we normally
964   // mean by containing_type().
965   m["extended_message_class"] =
966       ModuleLevelMessageName(*extension_field.containing_type());
967   m["field"] = FieldReferencingExpression(
968       extension_field.extension_scope(), extension_field, "extensions_by_name");
969   printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n");
970 }
971 
FixForeignFieldsInNestedExtensions(const Descriptor & descriptor) const972 void Generator::FixForeignFieldsInNestedExtensions(
973     const Descriptor& descriptor) const {
974   // Recursively fix up extensions in all nested types.
975   for (int i = 0; i < descriptor.nested_type_count(); ++i) {
976     FixForeignFieldsInNestedExtensions(*descriptor.nested_type(i));
977   }
978   // Fix up extensions directly contained within this type.
979   for (int i = 0; i < descriptor.extension_count(); ++i) {
980     FixForeignFieldsInExtension(*descriptor.extension(i));
981   }
982 }
983 
984 // Returns a Python expression that instantiates a Python EnumValueDescriptor
985 // object for the given C++ descriptor.
PrintEnumValueDescriptor(const EnumValueDescriptor & descriptor) const986 void Generator::PrintEnumValueDescriptor(
987     const EnumValueDescriptor& descriptor) const {
988   // TODO(robinson): Fix up EnumValueDescriptor "type" fields.
989   // More circular references.  ::sigh::
990   std::string options_string;
991   descriptor.options().SerializeToString(&options_string);
992   std::map<std::string, std::string> m;
993   m["name"] = descriptor.name();
994   m["index"] = StrCat(descriptor.index());
995   m["number"] = StrCat(descriptor.number());
996   m["options"] = OptionsValue(options_string);
997   printer_->Print(m,
998                   "_descriptor.EnumValueDescriptor(\n"
999                   "  name='$name$', index=$index$, number=$number$,\n"
1000                   "  serialized_options=$options$,\n"
1001                   "  type=None,\n"
1002                   "  create_key=_descriptor._internal_create_key)");
1003 }
1004 
1005 // Returns a CEscaped string of serialized_options.
OptionsValue(const std::string & serialized_options) const1006 std::string Generator::OptionsValue(
1007     const std::string& serialized_options) const {
1008   if (serialized_options.length() == 0 || GeneratingDescriptorProto()) {
1009     return "None";
1010   } else {
1011     return "b'" + CEscape(serialized_options) + "'";
1012   }
1013 }
1014 
1015 // Prints an expression for a Python FieldDescriptor for |field|.
PrintFieldDescriptor(const FieldDescriptor & field,bool is_extension) const1016 void Generator::PrintFieldDescriptor(const FieldDescriptor& field,
1017                                      bool is_extension) const {
1018   std::string options_string;
1019   field.options().SerializeToString(&options_string);
1020   std::map<std::string, std::string> m;
1021   m["name"] = field.name();
1022   m["full_name"] = field.full_name();
1023   m["index"] = StrCat(field.index());
1024   m["number"] = StrCat(field.number());
1025   m["type"] = StrCat(field.type());
1026   m["cpp_type"] = StrCat(field.cpp_type());
1027   m["label"] = StrCat(field.label());
1028   m["has_default_value"] = field.has_default_value() ? "True" : "False";
1029   m["default_value"] = StringifyDefaultValue(field);
1030   m["is_extension"] = is_extension ? "True" : "False";
1031   m["serialized_options"] = OptionsValue(options_string);
1032   m["json_name"] =
1033       field.has_json_name() ? ", json_name='" + field.json_name() + "'" : "";
1034   // We always set message_type and enum_type to None at this point, and then
1035   // these fields in correctly after all referenced descriptors have been
1036   // defined and/or imported (see FixForeignFieldsInDescriptors()).
1037   const char field_descriptor_decl[] =
1038       "_descriptor.FieldDescriptor(\n"
1039       "  name='$name$', full_name='$full_name$', index=$index$,\n"
1040       "  number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n"
1041       "  has_default_value=$has_default_value$, "
1042       "default_value=$default_value$,\n"
1043       "  message_type=None, enum_type=None, containing_type=None,\n"
1044       "  is_extension=$is_extension$, extension_scope=None,\n"
1045       "  serialized_options=$serialized_options$$json_name$, file=DESCRIPTOR,"
1046       "  create_key=_descriptor._internal_create_key)";
1047   printer_->Print(m, field_descriptor_decl);
1048 }
1049 
1050 // Helper for Print{Fields,Extensions}InDescriptor().
PrintFieldDescriptorsInDescriptor(const Descriptor & message_descriptor,bool is_extension,const std::string & list_variable_name,int (Descriptor::* CountFn)()const,const FieldDescriptor * (Descriptor::* GetterFn)(int)const) const1051 void Generator::PrintFieldDescriptorsInDescriptor(
1052     const Descriptor& message_descriptor, bool is_extension,
1053     const std::string& list_variable_name, int (Descriptor::*CountFn)() const,
1054     const FieldDescriptor* (Descriptor::*GetterFn)(int)const) const {
1055   printer_->Print("$list$=[\n", "list", list_variable_name);
1056   printer_->Indent();
1057   for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) {
1058     PrintFieldDescriptor(*(message_descriptor.*GetterFn)(i), is_extension);
1059     printer_->Print(",\n");
1060   }
1061   printer_->Outdent();
1062   printer_->Print("],\n");
1063 }
1064 
1065 // Prints a statement assigning "fields" to a list of Python FieldDescriptors,
1066 // one for each field present in message_descriptor.
PrintFieldsInDescriptor(const Descriptor & message_descriptor) const1067 void Generator::PrintFieldsInDescriptor(
1068     const Descriptor& message_descriptor) const {
1069   const bool is_extension = false;
1070   PrintFieldDescriptorsInDescriptor(message_descriptor, is_extension, "fields",
1071                                     &Descriptor::field_count,
1072                                     &Descriptor::field);
1073 }
1074 
1075 // Prints a statement assigning "extensions" to a list of Python
1076 // FieldDescriptors, one for each extension present in message_descriptor.
PrintExtensionsInDescriptor(const Descriptor & message_descriptor) const1077 void Generator::PrintExtensionsInDescriptor(
1078     const Descriptor& message_descriptor) const {
1079   const bool is_extension = true;
1080   PrintFieldDescriptorsInDescriptor(message_descriptor, is_extension,
1081                                     "extensions", &Descriptor::extension_count,
1082                                     &Descriptor::extension);
1083 }
1084 
GeneratingDescriptorProto() const1085 bool Generator::GeneratingDescriptorProto() const {
1086   return file_->name() == "net/proto2/proto/descriptor.proto" ||
1087          file_->name() == "google/protobuf/descriptor.proto";
1088 }
1089 
1090 // Returns the unique Python module-level identifier given to a descriptor.
1091 // This name is module-qualified iff the given descriptor describes an
1092 // entity that doesn't come from the current file.
1093 template <typename DescriptorT>
ModuleLevelDescriptorName(const DescriptorT & descriptor) const1094 std::string Generator::ModuleLevelDescriptorName(
1095     const DescriptorT& descriptor) const {
1096   // FIXME(robinson):
1097   // We currently don't worry about collisions with underscores in the type
1098   // names, so these would collide in nasty ways if found in the same file:
1099   //   OuterProto.ProtoA.ProtoB
1100   //   OuterProto_ProtoA.ProtoB  # Underscore instead of period.
1101   // As would these:
1102   //   OuterProto.ProtoA_.ProtoB
1103   //   OuterProto.ProtoA._ProtoB  # Leading vs. trailing underscore.
1104   // (Contrived, but certainly possible).
1105   //
1106   // The C++ implementation doesn't guard against this either.  Leaving
1107   // it for now...
1108   std::string name = NamePrefixedWithNestedTypes(descriptor, "_");
1109   ToUpper(&name);
1110   // Module-private for now.  Easy to make public later; almost impossible
1111   // to make private later.
1112   name = "_" + name;
1113   // We now have the name relative to its own module.  Also qualify with
1114   // the module name iff this descriptor is from a different .proto file.
1115   if (descriptor.file() != file_) {
1116     name = ModuleAlias(descriptor.file()->name()) + "." + name;
1117   }
1118   return name;
1119 }
1120 
1121 // Returns the name of the message class itself, not the descriptor.
1122 // Like ModuleLevelDescriptorName(), module-qualifies the name iff
1123 // the given descriptor describes an entity that doesn't come from
1124 // the current file.
ModuleLevelMessageName(const Descriptor & descriptor) const1125 std::string Generator::ModuleLevelMessageName(
1126     const Descriptor& descriptor) const {
1127   std::string name = NamePrefixedWithNestedTypes(descriptor, ".");
1128   if (descriptor.file() != file_) {
1129     name = ModuleAlias(descriptor.file()->name()) + "." + name;
1130   }
1131   return name;
1132 }
1133 
1134 // Returns the unique Python module-level identifier given to a service
1135 // descriptor.
ModuleLevelServiceDescriptorName(const ServiceDescriptor & descriptor) const1136 std::string Generator::ModuleLevelServiceDescriptorName(
1137     const ServiceDescriptor& descriptor) const {
1138   std::string name = descriptor.name();
1139   ToUpper(&name);
1140   name = "_" + name;
1141   if (descriptor.file() != file_) {
1142     name = ModuleAlias(descriptor.file()->name()) + "." + name;
1143   }
1144   return name;
1145 }
1146 
1147 // Prints standard constructor arguments serialized_start and serialized_end.
1148 // Args:
1149 //   descriptor: The cpp descriptor to have a serialized reference.
1150 //   proto: A proto
1151 // Example printer output:
1152 // serialized_start=41,
1153 // serialized_end=43,
1154 //
1155 template <typename DescriptorT, typename DescriptorProtoT>
PrintSerializedPbInterval(const DescriptorT & descriptor,DescriptorProtoT & proto,const std::string & name) const1156 void Generator::PrintSerializedPbInterval(const DescriptorT& descriptor,
1157                                           DescriptorProtoT& proto,
1158                                           const std::string& name) const {
1159   descriptor.CopyTo(&proto);
1160   std::string sp;
1161   proto.SerializeToString(&sp);
1162   int offset = file_descriptor_serialized_.find(sp);
1163   GOOGLE_CHECK_GE(offset, 0);
1164 
1165   printer_->Print(
1166       "$name$._serialized_start=$serialized_start$\n"
1167       "$name$._serialized_end=$serialized_end$\n",
1168       "name", name, "serialized_start", StrCat(offset), "serialized_end",
1169       StrCat(offset + sp.size()));
1170 }
1171 
1172 namespace {
PrintDescriptorOptionsFixingCode(const std::string & descriptor,const std::string & options,io::Printer * printer)1173 void PrintDescriptorOptionsFixingCode(const std::string& descriptor,
1174                                       const std::string& options,
1175                                       io::Printer* printer) {
1176   // Reset the _options to None thus DescriptorBase.GetOptions() can
1177   // parse _options again after extensions are registered.
1178   printer->Print(
1179       "$descriptor$._options = None\n"
1180       "$descriptor$._serialized_options = $serialized_value$\n",
1181       "descriptor", descriptor, "serialized_value", options);
1182 }
1183 }  // namespace
1184 
SetSerializedPbInterval() const1185 void Generator::SetSerializedPbInterval() const {
1186   // Top level enums.
1187   for (int i = 0; i < file_->enum_type_count(); ++i) {
1188     EnumDescriptorProto proto;
1189     const EnumDescriptor& descriptor = *file_->enum_type(i);
1190     PrintSerializedPbInterval(descriptor, proto,
1191                               ModuleLevelDescriptorName(descriptor));
1192   }
1193 
1194   // Messages.
1195   for (int i = 0; i < file_->message_type_count(); ++i) {
1196     SetMessagePbInterval(*file_->message_type(i));
1197   }
1198 
1199   // Services.
1200   for (int i = 0; i < file_->service_count(); ++i) {
1201     ServiceDescriptorProto proto;
1202     const ServiceDescriptor& service = *file_->service(i);
1203     PrintSerializedPbInterval(service, proto,
1204                               ModuleLevelServiceDescriptorName(service));
1205   }
1206 }
1207 
SetMessagePbInterval(const Descriptor & descriptor) const1208 void Generator::SetMessagePbInterval(const Descriptor& descriptor) const {
1209   DescriptorProto message_proto;
1210   PrintSerializedPbInterval(descriptor, message_proto,
1211                             ModuleLevelDescriptorName(descriptor));
1212 
1213   // Nested messages.
1214   for (int i = 0; i < descriptor.nested_type_count(); ++i) {
1215     SetMessagePbInterval(*descriptor.nested_type(i));
1216   }
1217 
1218   for (int i = 0; i < descriptor.enum_type_count(); ++i) {
1219     EnumDescriptorProto proto;
1220     const EnumDescriptor& enum_des = *descriptor.enum_type(i);
1221     PrintSerializedPbInterval(enum_des, proto,
1222                               ModuleLevelDescriptorName(enum_des));
1223   }
1224 }
1225 
1226 // Prints expressions that set the options field of all descriptors.
FixAllDescriptorOptions() const1227 void Generator::FixAllDescriptorOptions() const {
1228   // Prints an expression that sets the file descriptor's options.
1229   std::string file_options = OptionsValue(file_->options().SerializeAsString());
1230   if (file_options != "None") {
1231     PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_);
1232   } else {
1233     printer_->Print("DESCRIPTOR._options = None\n");
1234   }
1235   // Prints expressions that set the options for all top level enums.
1236   for (int i = 0; i < file_->enum_type_count(); ++i) {
1237     const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
1238     FixOptionsForEnum(enum_descriptor);
1239   }
1240   // Prints expressions that set the options for all top level extensions.
1241   for (int i = 0; i < file_->extension_count(); ++i) {
1242     const FieldDescriptor& field = *file_->extension(i);
1243     FixOptionsForField(field);
1244   }
1245   // Prints expressions that set the options for all messages, nested enums,
1246   // nested extensions and message fields.
1247   for (int i = 0; i < file_->message_type_count(); ++i) {
1248     FixOptionsForMessage(*file_->message_type(i));
1249   }
1250 
1251   for (int i = 0; i < file_->service_count(); ++i) {
1252     FixOptionsForService(*file_->service(i));
1253   }
1254 }
1255 
FixOptionsForOneof(const OneofDescriptor & oneof) const1256 void Generator::FixOptionsForOneof(const OneofDescriptor& oneof) const {
1257   std::string oneof_options = OptionsValue(oneof.options().SerializeAsString());
1258   if (oneof_options != "None") {
1259     std::string oneof_name = strings::Substitute(
1260         "$0.$1['$2']", ModuleLevelDescriptorName(*oneof.containing_type()),
1261         "oneofs_by_name", oneof.name());
1262     PrintDescriptorOptionsFixingCode(oneof_name, oneof_options, printer_);
1263   }
1264 }
1265 
1266 // Prints expressions that set the options for an enum descriptor and its
1267 // value descriptors.
FixOptionsForEnum(const EnumDescriptor & enum_descriptor) const1268 void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const {
1269   std::string descriptor_name = ModuleLevelDescriptorName(enum_descriptor);
1270   std::string enum_options =
1271       OptionsValue(enum_descriptor.options().SerializeAsString());
1272   if (enum_options != "None") {
1273     PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_);
1274   }
1275   for (int i = 0; i < enum_descriptor.value_count(); ++i) {
1276     const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i);
1277     std::string value_options =
1278         OptionsValue(value_descriptor.options().SerializeAsString());
1279     if (value_options != "None") {
1280       PrintDescriptorOptionsFixingCode(
1281           StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(),
1282                           value_descriptor.name().c_str()),
1283           value_options, printer_);
1284     }
1285   }
1286 }
1287 
1288 // Prints expressions that set the options for an service descriptor and its
1289 // value descriptors.
FixOptionsForService(const ServiceDescriptor & service_descriptor) const1290 void Generator::FixOptionsForService(
1291     const ServiceDescriptor& service_descriptor) const {
1292   std::string descriptor_name =
1293       ModuleLevelServiceDescriptorName(service_descriptor);
1294   std::string service_options =
1295       OptionsValue(service_descriptor.options().SerializeAsString());
1296   if (service_options != "None") {
1297     PrintDescriptorOptionsFixingCode(descriptor_name, service_options,
1298                                      printer_);
1299   }
1300 
1301   for (int i = 0; i < service_descriptor.method_count(); ++i) {
1302     const MethodDescriptor* method = service_descriptor.method(i);
1303     std::string method_options =
1304         OptionsValue(method->options().SerializeAsString());
1305     if (method_options != "None") {
1306       std::string method_name =
1307           descriptor_name + ".methods_by_name['" + method->name() + "']";
1308       PrintDescriptorOptionsFixingCode(method_name, method_options, printer_);
1309     }
1310   }
1311 }
1312 
1313 // Prints expressions that set the options for field descriptors (including
1314 // extensions).
FixOptionsForField(const FieldDescriptor & field) const1315 void Generator::FixOptionsForField(const FieldDescriptor& field) const {
1316   std::string field_options = OptionsValue(field.options().SerializeAsString());
1317   if (field_options != "None") {
1318     std::string field_name;
1319     if (field.is_extension()) {
1320       if (field.extension_scope() == nullptr) {
1321         // Top level extensions.
1322         field_name = field.name();
1323       } else {
1324         field_name = FieldReferencingExpression(field.extension_scope(), field,
1325                                                 "extensions_by_name");
1326       }
1327     } else {
1328       field_name = FieldReferencingExpression(field.containing_type(), field,
1329                                               "fields_by_name");
1330     }
1331     PrintDescriptorOptionsFixingCode(field_name, field_options, printer_);
1332   }
1333 }
1334 
1335 // Prints expressions that set the options for a message and all its inner
1336 // types (nested messages, nested enums, extensions, fields).
FixOptionsForMessage(const Descriptor & descriptor) const1337 void Generator::FixOptionsForMessage(const Descriptor& descriptor) const {
1338   // Nested messages.
1339   for (int i = 0; i < descriptor.nested_type_count(); ++i) {
1340     FixOptionsForMessage(*descriptor.nested_type(i));
1341   }
1342   // Oneofs.
1343   for (int i = 0; i < descriptor.oneof_decl_count(); ++i) {
1344     FixOptionsForOneof(*descriptor.oneof_decl(i));
1345   }
1346   // Enums.
1347   for (int i = 0; i < descriptor.enum_type_count(); ++i) {
1348     FixOptionsForEnum(*descriptor.enum_type(i));
1349   }
1350   // Fields.
1351   for (int i = 0; i < descriptor.field_count(); ++i) {
1352     const FieldDescriptor& field = *descriptor.field(i);
1353     FixOptionsForField(field);
1354   }
1355   // Extensions.
1356   for (int i = 0; i < descriptor.extension_count(); ++i) {
1357     const FieldDescriptor& field = *descriptor.extension(i);
1358     FixOptionsForField(field);
1359   }
1360   // Message option for this message.
1361   std::string message_options =
1362       OptionsValue(descriptor.options().SerializeAsString());
1363   if (message_options != "None") {
1364     std::string descriptor_name = ModuleLevelDescriptorName(descriptor);
1365     PrintDescriptorOptionsFixingCode(descriptor_name, message_options,
1366                                      printer_);
1367   }
1368 }
1369 
1370 // If a dependency forwards other files through public dependencies, let's
1371 // copy over the corresponding module aliases.
CopyPublicDependenciesAliases(const std::string & copy_from,const FileDescriptor * file) const1372 void Generator::CopyPublicDependenciesAliases(
1373     const std::string& copy_from, const FileDescriptor* file) const {
1374   for (int i = 0; i < file->public_dependency_count(); ++i) {
1375     std::string module_name = ModuleName(file->public_dependency(i)->name());
1376     std::string module_alias = ModuleAlias(file->public_dependency(i)->name());
1377     // There's no module alias in the dependent file if it was generated by
1378     // an old protoc (less than 3.0.0-alpha-1). Use module name in this
1379     // situation.
1380     printer_->Print(
1381         "try:\n"
1382         "  $alias$ = $copy_from$.$alias$\n"
1383         "except AttributeError:\n"
1384         "  $alias$ = $copy_from$.$module$\n",
1385         "alias", module_alias, "module", module_name, "copy_from", copy_from);
1386     CopyPublicDependenciesAliases(copy_from, file->public_dependency(i));
1387   }
1388 }
1389 
1390 }  // namespace python
1391 }  // namespace compiler
1392 }  // namespace protobuf
1393 }  // namespace google
1394