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