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