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