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 <limits>
48 #include <map>
49 #include <utility>
50 #include <memory>
51 #include <string>
52 #include <vector>
53 
54 #include <google/protobuf/compiler/python/python_generator.h>
55 #include <google/protobuf/descriptor.pb.h>
56 
57 #include <google/protobuf/stubs/common.h>
58 #include <google/protobuf/stubs/stringprintf.h>
59 #include <google/protobuf/io/printer.h>
60 #include <google/protobuf/descriptor.h>
61 #include <google/protobuf/io/zero_copy_stream.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 
72 // Returns a copy of |filename| with any trailing ".protodevel" or ".proto
73 // suffix stripped.
74 // TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc.
StripProto(const string & filename)75 string StripProto(const string& filename) {
76   const char* suffix = HasSuffixString(filename, ".protodevel")
77       ? ".protodevel" : ".proto";
78   return StripSuffixString(filename, suffix);
79 }
80 
81 
82 // Returns the Python module name expected for a given .proto filename.
ModuleName(const string & filename)83 string ModuleName(const string& filename) {
84   string basename = StripProto(filename);
85   StripString(&basename, "-", '_');
86   StripString(&basename, "/", '.');
87   return basename + "_pb2";
88 }
89 
90 
91 // Returns the name of all containing types for descriptor,
92 // in order from outermost to innermost, followed by descriptor's
93 // own name.  Each name is separated by |separator|.
94 template <typename DescriptorT>
NamePrefixedWithNestedTypes(const DescriptorT & descriptor,const string & separator)95 string NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
96                                    const string& separator) {
97   string name = descriptor.name();
98   for (const Descriptor* current = descriptor.containing_type();
99        current != NULL; current = current->containing_type()) {
100     name = current->name() + separator + name;
101   }
102   return name;
103 }
104 
105 
106 // Name of the class attribute where we store the Python
107 // descriptor.Descriptor instance for the generated class.
108 // Must stay consistent with the _DESCRIPTOR_KEY constant
109 // in proto2/public/reflection.py.
110 const char kDescriptorKey[] = "DESCRIPTOR";
111 
112 
113 // Does the file have top-level enums?
HasTopLevelEnums(const FileDescriptor * file)114 inline bool HasTopLevelEnums(const FileDescriptor *file) {
115   return file->enum_type_count() > 0;
116 }
117 
118 
119 // Should we generate generic services for this file?
HasGenericServices(const FileDescriptor * file)120 inline bool HasGenericServices(const FileDescriptor *file) {
121   return file->service_count() > 0 &&
122          file->options().py_generic_services();
123 }
124 
125 
126 // Prints the common boilerplate needed at the top of every .py
127 // file output by this generator.
PrintTopBoilerplate(io::Printer * printer,const FileDescriptor * file,bool descriptor_proto)128 void PrintTopBoilerplate(
129     io::Printer* printer, const FileDescriptor* file, bool descriptor_proto) {
130   // TODO(robinson): Allow parameterization of Python version?
131   printer->Print(
132       "# Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
133       "# source: $filename$\n"
134       "\nimport sys\n_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))"  //##PY25
135       "\n",
136       "filename", file->name());
137   if (HasTopLevelEnums(file)) {
138     printer->Print(
139         "from google.protobuf.internal import enum_type_wrapper\n");
140   }
141   printer->Print(
142       "from google.protobuf import descriptor as _descriptor\n"
143       "from google.protobuf import message as _message\n"
144       "from google.protobuf import reflection as _reflection\n"
145       "from google.protobuf import symbol_database as "
146       "_symbol_database\n");
147   if (HasGenericServices(file)) {
148     printer->Print(
149         "from google.protobuf import service as _service\n"
150         "from google.protobuf import service_reflection\n");
151   }
152 
153   // Avoid circular imports if this module is descriptor_pb2.
154   if (!descriptor_proto) {
155     printer->Print(
156         "from google.protobuf import descriptor_pb2\n");
157   }
158   printer->Print(
159       "# @@protoc_insertion_point(imports)\n\n"
160       "_sym_db = _symbol_database.Default()\n");
161   printer->Print("\n\n");
162 }
163 
164 
165 // Returns a Python literal giving the default value for a field.
166 // If the field specifies no explicit default value, we'll return
167 // the default default value for the field type (zero for numbers,
168 // empty string for strings, empty list for repeated fields, and
169 // None for non-repeated, composite fields).
170 //
171 // TODO(robinson): Unify with code from
172 // //compiler/cpp/internal/primitive_field.cc
173 // //compiler/cpp/internal/enum_field.cc
174 // //compiler/cpp/internal/string_field.cc
StringifyDefaultValue(const FieldDescriptor & field)175 string StringifyDefaultValue(const FieldDescriptor& field) {
176   if (field.is_repeated()) {
177     return "[]";
178   }
179 
180   switch (field.cpp_type()) {
181     case FieldDescriptor::CPPTYPE_INT32:
182       return SimpleItoa(field.default_value_int32());
183     case FieldDescriptor::CPPTYPE_UINT32:
184       return SimpleItoa(field.default_value_uint32());
185     case FieldDescriptor::CPPTYPE_INT64:
186       return SimpleItoa(field.default_value_int64());
187     case FieldDescriptor::CPPTYPE_UINT64:
188       return SimpleItoa(field.default_value_uint64());
189     case FieldDescriptor::CPPTYPE_DOUBLE: {
190       double value = field.default_value_double();
191       if (value == numeric_limits<double>::infinity()) {
192         // Python pre-2.6 on Windows does not parse "inf" correctly.  However,
193         // a numeric literal that is too big for a double will become infinity.
194         return "1e10000";
195       } else if (value == -numeric_limits<double>::infinity()) {
196         // See above.
197         return "-1e10000";
198       } else if (value != value) {
199         // infinity * 0 = nan
200         return "(1e10000 * 0)";
201       } else {
202         return SimpleDtoa(value);
203       }
204     }
205     case FieldDescriptor::CPPTYPE_FLOAT: {
206       float value = field.default_value_float();
207       if (value == numeric_limits<float>::infinity()) {
208         // Python pre-2.6 on Windows does not parse "inf" correctly.  However,
209         // a numeric literal that is too big for a double will become infinity.
210         return "1e10000";
211       } else if (value == -numeric_limits<float>::infinity()) {
212         // See above.
213         return "-1e10000";
214       } else if (value != value) {
215         // infinity - infinity = nan
216         return "(1e10000 * 0)";
217       } else {
218         return SimpleFtoa(value);
219       }
220     }
221     case FieldDescriptor::CPPTYPE_BOOL:
222       return field.default_value_bool() ? "True" : "False";
223     case FieldDescriptor::CPPTYPE_ENUM:
224       return SimpleItoa(field.default_value_enum()->number());
225     case FieldDescriptor::CPPTYPE_STRING:
226 //##!PY25      return "b\"" + CEscape(field.default_value_string()) +
227 //##!PY25             (field.type() != FieldDescriptor::TYPE_STRING ? "\"" :
228 //##!PY25               "\".decode('utf-8')");
229       return "_b(\"" + CEscape(field.default_value_string()) +  //##PY25
230              (field.type() != FieldDescriptor::TYPE_STRING ? "\")" :  //##PY25
231                "\").decode('utf-8')");  //##PY25
232     case FieldDescriptor::CPPTYPE_MESSAGE:
233       return "None";
234   }
235   // (We could add a default case above but then we wouldn't get the nice
236   // compiler warning when a new type is added.)
237   GOOGLE_LOG(FATAL) << "Not reached.";
238   return "";
239 }
240 
241 
242 
243 }  // namespace
244 
245 
Generator()246 Generator::Generator() : file_(NULL) {
247 }
248 
~Generator()249 Generator::~Generator() {
250 }
251 
Generate(const FileDescriptor * file,const string & parameter,GeneratorContext * context,string * error) const252 bool Generator::Generate(const FileDescriptor* file,
253                          const string& parameter,
254                          GeneratorContext* context,
255                          string* error) const {
256 
257   // Completely serialize all Generate() calls on this instance.  The
258   // thread-safety constraints of the CodeGenerator interface aren't clear so
259   // just be as conservative as possible.  It's easier to relax this later if
260   // we need to, but I doubt it will be an issue.
261   // TODO(kenton):  The proper thing to do would be to allocate any state on
262   //   the stack and use that, so that the Generator class itself does not need
263   //   to have any mutable members.  Then it is implicitly thread-safe.
264   MutexLock lock(&mutex_);
265   file_ = file;
266   string module_name = ModuleName(file->name());
267   string filename = module_name;
268   StripString(&filename, ".", '/');
269   filename += ".py";
270 
271   FileDescriptorProto fdp;
272   file_->CopyTo(&fdp);
273   fdp.SerializeToString(&file_descriptor_serialized_);
274 
275 
276   scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
277   GOOGLE_CHECK(output.get());
278   io::Printer printer(output.get(), '$');
279   printer_ = &printer;
280 
281   PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
282   PrintImports();
283   PrintFileDescriptor();
284   PrintTopLevelEnums();
285   PrintTopLevelExtensions();
286   PrintAllNestedEnumsInFile();
287   PrintMessageDescriptors();
288   FixForeignFieldsInDescriptors();
289   PrintMessages();
290   // We have to fix up the extensions after the message classes themselves,
291   // since they need to call static RegisterExtension() methods on these
292   // classes.
293   FixForeignFieldsInExtensions();
294   // Descriptor options may have custom extensions. These custom options
295   // can only be successfully parsed after we register corresponding
296   // extensions. Therefore we parse all options again here to recognize
297   // custom options that may be unknown when we define the descriptors.
298   FixAllDescriptorOptions();
299   if (HasGenericServices(file)) {
300     PrintServices();
301   }
302 
303   printer.Print(
304     "# @@protoc_insertion_point(module_scope)\n");
305 
306   return !printer.failed();
307 }
308 
309 // Prints Python imports for all modules imported by |file|.
PrintImports() const310 void Generator::PrintImports() const {
311   for (int i = 0; i < file_->dependency_count(); ++i) {
312     string module_name = ModuleName(file_->dependency(i)->name());
313     printer_->Print("import $module$\n", "module",
314                     module_name);
315   }
316   printer_->Print("\n");
317 
318   // Print public imports.
319   for (int i = 0; i < file_->public_dependency_count(); ++i) {
320     string module_name = ModuleName(file_->public_dependency(i)->name());
321     printer_->Print("from $module$ import *\n", "module", module_name);
322   }
323   printer_->Print("\n");
324 }
325 
326 // Prints the single file descriptor for this file.
PrintFileDescriptor() const327 void Generator::PrintFileDescriptor() const {
328   map<string, string> m;
329   m["descriptor_name"] = kDescriptorKey;
330   m["name"] = file_->name();
331   m["package"] = file_->package();
332   const char file_descriptor_template[] =
333       "$descriptor_name$ = _descriptor.FileDescriptor(\n"
334       "  name='$name$',\n"
335       "  package='$package$',\n";
336   printer_->Print(m, file_descriptor_template);
337   printer_->Indent();
338   printer_->Print(
339 //##!PY25      "serialized_pb=b'$value$'\n",
340       "serialized_pb=_b('$value$')\n",  //##PY25
341       "value", strings::CHexEscape(file_descriptor_serialized_));
342   if (file_->dependency_count() != 0) {
343     printer_->Print(",\ndependencies=[");
344     for (int i = 0; i < file_->dependency_count(); ++i) {
345       string module_name = ModuleName(file_->dependency(i)->name());
346       printer_->Print("$module_name$.DESCRIPTOR,", "module_name", module_name);
347     }
348     printer_->Print("]");
349   }
350 
351   // TODO(falk): Also print options and fix the message_type, enum_type,
352   //             service and extension later in the generation.
353 
354   printer_->Outdent();
355   printer_->Print(")\n");
356   printer_->Print("_sym_db.RegisterFileDescriptor($name$)\n", "name",
357                   kDescriptorKey);
358   printer_->Print("\n");
359 }
360 
361 // Prints descriptors and module-level constants for all top-level
362 // enums defined in |file|.
PrintTopLevelEnums() const363 void Generator::PrintTopLevelEnums() const {
364   vector<pair<string, int> > top_level_enum_values;
365   for (int i = 0; i < file_->enum_type_count(); ++i) {
366     const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
367     PrintEnum(enum_descriptor);
368     printer_->Print("$name$ = "
369                     "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)",
370                     "name", enum_descriptor.name(),
371                     "descriptor_name",
372                     ModuleLevelDescriptorName(enum_descriptor));
373     printer_->Print("\n");
374 
375     for (int j = 0; j < enum_descriptor.value_count(); ++j) {
376       const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j);
377       top_level_enum_values.push_back(
378           make_pair(value_descriptor.name(), value_descriptor.number()));
379     }
380   }
381 
382   for (int i = 0; i < top_level_enum_values.size(); ++i) {
383     printer_->Print("$name$ = $value$\n",
384                     "name", top_level_enum_values[i].first,
385                     "value", SimpleItoa(top_level_enum_values[i].second));
386   }
387   printer_->Print("\n");
388 }
389 
390 // Prints all enums contained in all message types in |file|.
PrintAllNestedEnumsInFile() const391 void Generator::PrintAllNestedEnumsInFile() const {
392   for (int i = 0; i < file_->message_type_count(); ++i) {
393     PrintNestedEnums(*file_->message_type(i));
394   }
395 }
396 
397 // Prints a Python statement assigning the appropriate module-level
398 // enum name to a Python EnumDescriptor object equivalent to
399 // enum_descriptor.
PrintEnum(const EnumDescriptor & enum_descriptor) const400 void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
401   map<string, string> m;
402   string module_level_descriptor_name =
403       ModuleLevelDescriptorName(enum_descriptor);
404   m["descriptor_name"] = module_level_descriptor_name;
405   m["name"] = enum_descriptor.name();
406   m["full_name"] = enum_descriptor.full_name();
407   m["file"] = kDescriptorKey;
408   const char enum_descriptor_template[] =
409       "$descriptor_name$ = _descriptor.EnumDescriptor(\n"
410       "  name='$name$',\n"
411       "  full_name='$full_name$',\n"
412       "  filename=None,\n"
413       "  file=$file$,\n"
414       "  values=[\n";
415   string options_string;
416   enum_descriptor.options().SerializeToString(&options_string);
417   printer_->Print(m, enum_descriptor_template);
418   printer_->Indent();
419   printer_->Indent();
420   for (int i = 0; i < enum_descriptor.value_count(); ++i) {
421     PrintEnumValueDescriptor(*enum_descriptor.value(i));
422     printer_->Print(",\n");
423   }
424   printer_->Outdent();
425   printer_->Print("],\n");
426   printer_->Print("containing_type=None,\n");
427   printer_->Print("options=$options_value$,\n",
428                   "options_value",
429                   OptionsValue("EnumOptions", options_string));
430   EnumDescriptorProto edp;
431   PrintSerializedPbInterval(enum_descriptor, edp);
432   printer_->Outdent();
433   printer_->Print(")\n");
434   printer_->Print("_sym_db.RegisterEnumDescriptor($name$)\n", "name",
435                   module_level_descriptor_name);
436   printer_->Print("\n");
437 }
438 
439 // Recursively prints enums in nested types within descriptor, then
440 // prints enums contained at the top level in descriptor.
PrintNestedEnums(const Descriptor & descriptor) const441 void Generator::PrintNestedEnums(const Descriptor& descriptor) const {
442   for (int i = 0; i < descriptor.nested_type_count(); ++i) {
443     PrintNestedEnums(*descriptor.nested_type(i));
444   }
445 
446   for (int i = 0; i < descriptor.enum_type_count(); ++i) {
447     PrintEnum(*descriptor.enum_type(i));
448   }
449 }
450 
PrintTopLevelExtensions() const451 void Generator::PrintTopLevelExtensions() const {
452   const bool is_extension = true;
453   for (int i = 0; i < file_->extension_count(); ++i) {
454     const FieldDescriptor& extension_field = *file_->extension(i);
455     string constant_name = extension_field.name() + "_FIELD_NUMBER";
456     UpperString(&constant_name);
457     printer_->Print("$constant_name$ = $number$\n",
458       "constant_name", constant_name,
459       "number", SimpleItoa(extension_field.number()));
460     printer_->Print("$name$ = ", "name", extension_field.name());
461     PrintFieldDescriptor(extension_field, is_extension);
462     printer_->Print("\n");
463   }
464   printer_->Print("\n");
465 }
466 
467 // Prints Python equivalents of all Descriptors in |file|.
PrintMessageDescriptors() const468 void Generator::PrintMessageDescriptors() const {
469   for (int i = 0; i < file_->message_type_count(); ++i) {
470     PrintDescriptor(*file_->message_type(i));
471     printer_->Print("\n");
472   }
473 }
474 
PrintServices() const475 void Generator::PrintServices() const {
476   for (int i = 0; i < file_->service_count(); ++i) {
477     PrintServiceDescriptor(*file_->service(i));
478     PrintServiceClass(*file_->service(i));
479     PrintServiceStub(*file_->service(i));
480     printer_->Print("\n");
481   }
482 }
483 
PrintServiceDescriptor(const ServiceDescriptor & descriptor) const484 void Generator::PrintServiceDescriptor(
485     const ServiceDescriptor& descriptor) const {
486   printer_->Print("\n");
487   string service_name = ModuleLevelServiceDescriptorName(descriptor);
488   string options_string;
489   descriptor.options().SerializeToString(&options_string);
490 
491   printer_->Print(
492       "$service_name$ = _descriptor.ServiceDescriptor(\n",
493       "service_name", service_name);
494   printer_->Indent();
495   map<string, string> m;
496   m["name"] = descriptor.name();
497   m["full_name"] = descriptor.full_name();
498   m["file"] = kDescriptorKey;
499   m["index"] = SimpleItoa(descriptor.index());
500   m["options_value"] = OptionsValue("ServiceOptions", options_string);
501   const char required_function_arguments[] =
502       "name='$name$',\n"
503       "full_name='$full_name$',\n"
504       "file=$file$,\n"
505       "index=$index$,\n"
506       "options=$options_value$,\n";
507   printer_->Print(m, required_function_arguments);
508 
509   ServiceDescriptorProto sdp;
510   PrintSerializedPbInterval(descriptor, sdp);
511 
512   printer_->Print("methods=[\n");
513   for (int i = 0; i < descriptor.method_count(); ++i) {
514     const MethodDescriptor* method = descriptor.method(i);
515     method->options().SerializeToString(&options_string);
516 
517     m.clear();
518     m["name"] = method->name();
519     m["full_name"] = method->full_name();
520     m["index"] = SimpleItoa(method->index());
521     m["serialized_options"] = CEscape(options_string);
522     m["input_type"] = ModuleLevelDescriptorName(*(method->input_type()));
523     m["output_type"] = ModuleLevelDescriptorName(*(method->output_type()));
524     m["options_value"] = OptionsValue("MethodOptions", options_string);
525     printer_->Print("_descriptor.MethodDescriptor(\n");
526     printer_->Indent();
527     printer_->Print(
528         m,
529         "name='$name$',\n"
530         "full_name='$full_name$',\n"
531         "index=$index$,\n"
532         "containing_service=None,\n"
533         "input_type=$input_type$,\n"
534         "output_type=$output_type$,\n"
535         "options=$options_value$,\n");
536     printer_->Outdent();
537     printer_->Print("),\n");
538   }
539 
540   printer_->Outdent();
541   printer_->Print("])\n\n");
542 }
543 
PrintServiceClass(const ServiceDescriptor & descriptor) const544 void Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const {
545   // Print the service.
546   printer_->Print("$class_name$ = service_reflection.GeneratedServiceType("
547                   "'$class_name$', (_service.Service,), dict(\n",
548                   "class_name", descriptor.name());
549   printer_->Indent();
550   printer_->Print(
551       "$descriptor_key$ = $descriptor_name$,\n",
552       "descriptor_key", kDescriptorKey,
553       "descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
554   printer_->Print(
555       "__module__ = '$module_name$'\n",
556       "module_name", ModuleName(file_->name()));
557   printer_->Print("))\n\n");
558   printer_->Outdent();
559 }
560 
PrintServiceStub(const ServiceDescriptor & descriptor) const561 void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const {
562   // Print the service stub.
563   printer_->Print("$class_name$_Stub = "
564                   "service_reflection.GeneratedServiceStubType("
565                   "'$class_name$_Stub', ($class_name$,), dict(\n",
566                   "class_name", descriptor.name());
567   printer_->Indent();
568   printer_->Print(
569       "$descriptor_key$ = $descriptor_name$,\n",
570       "descriptor_key", kDescriptorKey,
571       "descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
572   printer_->Print(
573       "__module__ = '$module_name$'\n",
574       "module_name", ModuleName(file_->name()));
575   printer_->Print("))\n\n");
576   printer_->Outdent();
577 }
578 
579 // Prints statement assigning ModuleLevelDescriptorName(message_descriptor)
580 // to a Python Descriptor object for message_descriptor.
581 //
582 // Mutually recursive with PrintNestedDescriptors().
PrintDescriptor(const Descriptor & message_descriptor) const583 void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
584   PrintNestedDescriptors(message_descriptor);
585 
586   printer_->Print("\n");
587   printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n",
588                   "descriptor_name",
589                   ModuleLevelDescriptorName(message_descriptor));
590   printer_->Indent();
591   map<string, string> m;
592   m["name"] = message_descriptor.name();
593   m["full_name"] = message_descriptor.full_name();
594   m["file"] = kDescriptorKey;
595   const char required_function_arguments[] =
596       "name='$name$',\n"
597       "full_name='$full_name$',\n"
598       "filename=None,\n"
599       "file=$file$,\n"
600       "containing_type=None,\n";
601   printer_->Print(m, required_function_arguments);
602   PrintFieldsInDescriptor(message_descriptor);
603   PrintExtensionsInDescriptor(message_descriptor);
604 
605   // Nested types
606   printer_->Print("nested_types=[");
607   for (int i = 0; i < message_descriptor.nested_type_count(); ++i) {
608     const string nested_name = ModuleLevelDescriptorName(
609         *message_descriptor.nested_type(i));
610     printer_->Print("$name$, ", "name", nested_name);
611   }
612   printer_->Print("],\n");
613 
614   // Enum types
615   printer_->Print("enum_types=[\n");
616   printer_->Indent();
617   for (int i = 0; i < message_descriptor.enum_type_count(); ++i) {
618     const string descriptor_name = ModuleLevelDescriptorName(
619         *message_descriptor.enum_type(i));
620     printer_->Print(descriptor_name.c_str());
621     printer_->Print(",\n");
622   }
623   printer_->Outdent();
624   printer_->Print("],\n");
625   string options_string;
626   message_descriptor.options().SerializeToString(&options_string);
627   printer_->Print(
628       "options=$options_value$,\n"
629       "is_extendable=$extendable$",
630       "options_value", OptionsValue("MessageOptions", options_string),
631       "extendable", message_descriptor.extension_range_count() > 0 ?
632                       "True" : "False");
633   printer_->Print(",\n");
634 
635   // Extension ranges
636   printer_->Print("extension_ranges=[");
637   for (int i = 0; i < message_descriptor.extension_range_count(); ++i) {
638     const Descriptor::ExtensionRange* range =
639         message_descriptor.extension_range(i);
640     printer_->Print("($start$, $end$), ",
641                     "start", SimpleItoa(range->start),
642                     "end", SimpleItoa(range->end));
643   }
644   printer_->Print("],\n");
645   printer_->Print("oneofs=[\n");
646   printer_->Indent();
647   for (int i = 0; i < message_descriptor.oneof_decl_count(); ++i) {
648     const OneofDescriptor* desc = message_descriptor.oneof_decl(i);
649     map<string, string> m;
650     m["name"] = desc->name();
651     m["full_name"] = desc->full_name();
652     m["index"] = SimpleItoa(desc->index());
653     printer_->Print(
654         m,
655         "_descriptor.OneofDescriptor(\n"
656         "  name='$name$', full_name='$full_name$',\n"
657         "  index=$index$, containing_type=None, fields=[]),\n");
658   }
659   printer_->Outdent();
660   printer_->Print("],\n");
661   // Serialization of proto
662   DescriptorProto edp;
663   PrintSerializedPbInterval(message_descriptor, edp);
664 
665   printer_->Outdent();
666   printer_->Print(")\n");
667 }
668 
669 // Prints Python Descriptor objects for all nested types contained in
670 // message_descriptor.
671 //
672 // Mutually recursive with PrintDescriptor().
PrintNestedDescriptors(const Descriptor & containing_descriptor) const673 void Generator::PrintNestedDescriptors(
674     const Descriptor& containing_descriptor) const {
675   for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
676     PrintDescriptor(*containing_descriptor.nested_type(i));
677   }
678 }
679 
680 // Prints all messages in |file|.
PrintMessages() const681 void Generator::PrintMessages() const {
682   for (int i = 0; i < file_->message_type_count(); ++i) {
683     vector<string> to_register;
684     PrintMessage(*file_->message_type(i), "", &to_register);
685     for (int j = 0; j < to_register.size(); ++j) {
686       printer_->Print("_sym_db.RegisterMessage($name$)\n", "name",
687                       to_register[j]);
688     }
689     printer_->Print("\n");
690   }
691 }
692 
693 // Prints a Python class for the given message descriptor.  We defer to the
694 // metaclass to do almost all of the work of actually creating a useful class.
695 // The purpose of this function and its many helper functions above is merely
696 // to output a Python version of the descriptors, which the metaclass in
697 // reflection.py will use to construct the meat of the class itself.
698 //
699 // Mutually recursive with PrintNestedMessages().
700 // Collect nested message names to_register for the symbol_database.
PrintMessage(const Descriptor & message_descriptor,const string & prefix,vector<string> * to_register) const701 void Generator::PrintMessage(const Descriptor& message_descriptor,
702                              const string& prefix,
703                              vector<string>* to_register) const {
704   string qualified_name(prefix + message_descriptor.name());
705   to_register->push_back(qualified_name);
706   printer_->Print(
707       "$name$ = _reflection.GeneratedProtocolMessageType('$name$', "
708       "(_message.Message,), dict(\n",
709       "name", message_descriptor.name());
710   printer_->Indent();
711 
712   PrintNestedMessages(message_descriptor, qualified_name + ".", to_register);
713   map<string, string> m;
714   m["descriptor_key"] = kDescriptorKey;
715   m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
716   printer_->Print(m, "$descriptor_key$ = $descriptor_name$,\n");
717   printer_->Print("__module__ = '$module_name$'\n",
718                   "module_name", ModuleName(file_->name()));
719   printer_->Print("# @@protoc_insertion_point(class_scope:$full_name$)\n",
720                   "full_name", message_descriptor.full_name());
721   printer_->Print("))\n");
722   printer_->Outdent();
723 }
724 
725 // Prints all nested messages within |containing_descriptor|.
726 // Mutually recursive with PrintMessage().
PrintNestedMessages(const Descriptor & containing_descriptor,const string & prefix,vector<string> * to_register) const727 void Generator::PrintNestedMessages(const Descriptor& containing_descriptor,
728                                     const string& prefix,
729                                     vector<string>* to_register) const {
730   for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
731     printer_->Print("\n");
732     PrintMessage(*containing_descriptor.nested_type(i), prefix, to_register);
733     printer_->Print(",\n");
734   }
735 }
736 
737 // Recursively fixes foreign fields in all nested types in |descriptor|, then
738 // sets the message_type and enum_type of all message and enum fields to point
739 // to their respective descriptors.
740 // Args:
741 //   descriptor: descriptor to print fields for.
742 //   containing_descriptor: if descriptor is a nested type, this is its
743 //       containing type, or NULL if this is a root/top-level type.
FixForeignFieldsInDescriptor(const Descriptor & descriptor,const Descriptor * containing_descriptor) const744 void Generator::FixForeignFieldsInDescriptor(
745     const Descriptor& descriptor,
746     const Descriptor* containing_descriptor) const {
747   for (int i = 0; i < descriptor.nested_type_count(); ++i) {
748     FixForeignFieldsInDescriptor(*descriptor.nested_type(i), &descriptor);
749   }
750 
751   for (int i = 0; i < descriptor.field_count(); ++i) {
752     const FieldDescriptor& field_descriptor = *descriptor.field(i);
753     FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name");
754   }
755 
756   FixContainingTypeInDescriptor(descriptor, containing_descriptor);
757   for (int i = 0; i < descriptor.enum_type_count(); ++i) {
758     const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i);
759     FixContainingTypeInDescriptor(enum_descriptor, &descriptor);
760   }
761   for (int i = 0; i < descriptor.oneof_decl_count(); ++i) {
762     map<string, string> m;
763     const OneofDescriptor* oneof = descriptor.oneof_decl(i);
764     m["descriptor_name"] = ModuleLevelDescriptorName(descriptor);
765     m["oneof_name"] = oneof->name();
766     for (int j = 0; j < oneof->field_count(); ++j) {
767       m["field_name"] = oneof->field(j)->name();
768       printer_->Print(
769           m,
770           "$descriptor_name$.oneofs_by_name['$oneof_name$'].fields.append(\n"
771           "  $descriptor_name$.fields_by_name['$field_name$'])\n");
772       printer_->Print(
773           m,
774           "$descriptor_name$.fields_by_name['$field_name$'].containing_oneof = "
775           "$descriptor_name$.oneofs_by_name['$oneof_name$']\n");
776     }
777   }
778 }
779 
AddMessageToFileDescriptor(const Descriptor & descriptor) const780 void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const {
781   map<string, string> m;
782   m["descriptor_name"] = kDescriptorKey;
783   m["message_name"] = descriptor.name();
784   m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
785   const char file_descriptor_template[] =
786       "$descriptor_name$.message_types_by_name['$message_name$'] = "
787       "$message_descriptor_name$\n";
788   printer_->Print(m, file_descriptor_template);
789 }
790 
AddEnumToFileDescriptor(const EnumDescriptor & descriptor) const791 void Generator::AddEnumToFileDescriptor(
792     const EnumDescriptor& descriptor) const {
793   map<string, string> m;
794   m["descriptor_name"] = kDescriptorKey;
795   m["enum_name"] = descriptor.name();
796   m["enum_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
797   const char file_descriptor_template[] =
798       "$descriptor_name$.enum_types_by_name['$enum_name$'] = "
799       "$enum_descriptor_name$\n";
800   printer_->Print(m, file_descriptor_template);
801 }
802 
AddExtensionToFileDescriptor(const FieldDescriptor & descriptor) const803 void Generator::AddExtensionToFileDescriptor(
804     const FieldDescriptor& descriptor) const {
805   map<string, string> m;
806   m["descriptor_name"] = kDescriptorKey;
807   m["field_name"] = descriptor.name();
808   const char file_descriptor_template[] =
809       "$descriptor_name$.extensions_by_name['$field_name$'] = "
810       "$field_name$\n";
811   printer_->Print(m, file_descriptor_template);
812 }
813 
814 // Sets any necessary message_type and enum_type attributes
815 // for the Python version of |field|.
816 //
817 // containing_type may be NULL, in which case this is a module-level field.
818 //
819 // python_dict_name is the name of the Python dict where we should
820 // look the field up in the containing type.  (e.g., fields_by_name
821 // or extensions_by_name).  We ignore python_dict_name if containing_type
822 // is NULL.
FixForeignFieldsInField(const Descriptor * containing_type,const FieldDescriptor & field,const string & python_dict_name) const823 void Generator::FixForeignFieldsInField(const Descriptor* containing_type,
824                                         const FieldDescriptor& field,
825                                         const string& python_dict_name) const {
826   const string field_referencing_expression = FieldReferencingExpression(
827       containing_type, field, python_dict_name);
828   map<string, string> m;
829   m["field_ref"] = field_referencing_expression;
830   const Descriptor* foreign_message_type = field.message_type();
831   if (foreign_message_type) {
832     m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type);
833     printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n");
834   }
835   const EnumDescriptor* enum_type = field.enum_type();
836   if (enum_type) {
837     m["enum_type"] = ModuleLevelDescriptorName(*enum_type);
838     printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n");
839   }
840 }
841 
842 // Returns the module-level expression for the given FieldDescriptor.
843 // Only works for fields in the .proto file this Generator is generating for.
844 //
845 // containing_type may be NULL, in which case this is a module-level field.
846 //
847 // python_dict_name is the name of the Python dict where we should
848 // look the field up in the containing type.  (e.g., fields_by_name
849 // or extensions_by_name).  We ignore python_dict_name if containing_type
850 // is NULL.
FieldReferencingExpression(const Descriptor * containing_type,const FieldDescriptor & field,const string & python_dict_name) const851 string Generator::FieldReferencingExpression(
852     const Descriptor* containing_type,
853     const FieldDescriptor& field,
854     const string& python_dict_name) const {
855   // We should only ever be looking up fields in the current file.
856   // The only things we refer to from other files are message descriptors.
857   GOOGLE_CHECK_EQ(field.file(), file_) << field.file()->name() << " vs. "
858                                 << file_->name();
859   if (!containing_type) {
860     return field.name();
861   }
862   return strings::Substitute(
863       "$0.$1['$2']",
864       ModuleLevelDescriptorName(*containing_type),
865       python_dict_name, field.name());
866 }
867 
868 // Prints containing_type for nested descriptors or enum descriptors.
869 template <typename DescriptorT>
FixContainingTypeInDescriptor(const DescriptorT & descriptor,const Descriptor * containing_descriptor) const870 void Generator::FixContainingTypeInDescriptor(
871     const DescriptorT& descriptor,
872     const Descriptor* containing_descriptor) const {
873   if (containing_descriptor != NULL) {
874     const string nested_name = ModuleLevelDescriptorName(descriptor);
875     const string parent_name = ModuleLevelDescriptorName(
876         *containing_descriptor);
877     printer_->Print(
878         "$nested_name$.containing_type = $parent_name$\n",
879         "nested_name", nested_name,
880         "parent_name", parent_name);
881   }
882 }
883 
884 // Prints statements setting the message_type and enum_type fields in the
885 // Python descriptor objects we've already output in ths file.  We must
886 // do this in a separate step due to circular references (otherwise, we'd
887 // just set everything in the initial assignment statements).
FixForeignFieldsInDescriptors() const888 void Generator::FixForeignFieldsInDescriptors() const {
889   for (int i = 0; i < file_->message_type_count(); ++i) {
890     FixForeignFieldsInDescriptor(*file_->message_type(i), NULL);
891   }
892   for (int i = 0; i < file_->message_type_count(); ++i) {
893     AddMessageToFileDescriptor(*file_->message_type(i));
894   }
895   for (int i = 0; i < file_->enum_type_count(); ++i) {
896     AddEnumToFileDescriptor(*file_->enum_type(i));
897   }
898   for (int i = 0; i < file_->extension_count(); ++i) {
899     AddExtensionToFileDescriptor(*file_->extension(i));
900   }
901   printer_->Print("\n");
902 }
903 
904 // We need to not only set any necessary message_type fields, but
905 // also need to call RegisterExtension() on each message we're
906 // extending.
FixForeignFieldsInExtensions() const907 void Generator::FixForeignFieldsInExtensions() const {
908   // Top-level extensions.
909   for (int i = 0; i < file_->extension_count(); ++i) {
910     FixForeignFieldsInExtension(*file_->extension(i));
911   }
912   // Nested extensions.
913   for (int i = 0; i < file_->message_type_count(); ++i) {
914     FixForeignFieldsInNestedExtensions(*file_->message_type(i));
915   }
916   printer_->Print("\n");
917 }
918 
FixForeignFieldsInExtension(const FieldDescriptor & extension_field) const919 void Generator::FixForeignFieldsInExtension(
920     const FieldDescriptor& extension_field) const {
921   GOOGLE_CHECK(extension_field.is_extension());
922   // extension_scope() will be NULL for top-level extensions, which is
923   // exactly what FixForeignFieldsInField() wants.
924   FixForeignFieldsInField(extension_field.extension_scope(), extension_field,
925                           "extensions_by_name");
926 
927   map<string, string> m;
928   // Confusingly, for FieldDescriptors that happen to be extensions,
929   // containing_type() means "extended type."
930   // On the other hand, extension_scope() will give us what we normally
931   // mean by containing_type().
932   m["extended_message_class"] = ModuleLevelMessageName(
933       *extension_field.containing_type());
934   m["field"] = FieldReferencingExpression(extension_field.extension_scope(),
935                                           extension_field,
936                                           "extensions_by_name");
937   printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n");
938 }
939 
FixForeignFieldsInNestedExtensions(const Descriptor & descriptor) const940 void Generator::FixForeignFieldsInNestedExtensions(
941     const Descriptor& descriptor) const {
942   // Recursively fix up extensions in all nested types.
943   for (int i = 0; i < descriptor.nested_type_count(); ++i) {
944     FixForeignFieldsInNestedExtensions(*descriptor.nested_type(i));
945   }
946   // Fix up extensions directly contained within this type.
947   for (int i = 0; i < descriptor.extension_count(); ++i) {
948     FixForeignFieldsInExtension(*descriptor.extension(i));
949   }
950 }
951 
952 // Returns a Python expression that instantiates a Python EnumValueDescriptor
953 // object for the given C++ descriptor.
PrintEnumValueDescriptor(const EnumValueDescriptor & descriptor) const954 void Generator::PrintEnumValueDescriptor(
955     const EnumValueDescriptor& descriptor) const {
956   // TODO(robinson): Fix up EnumValueDescriptor "type" fields.
957   // More circular references.  ::sigh::
958   string options_string;
959   descriptor.options().SerializeToString(&options_string);
960   map<string, string> m;
961   m["name"] = descriptor.name();
962   m["index"] = SimpleItoa(descriptor.index());
963   m["number"] = SimpleItoa(descriptor.number());
964   m["options"] = OptionsValue("EnumValueOptions", options_string);
965   printer_->Print(
966       m,
967       "_descriptor.EnumValueDescriptor(\n"
968       "  name='$name$', index=$index$, number=$number$,\n"
969       "  options=$options$,\n"
970       "  type=None)");
971 }
972 
973 // Returns a Python expression that calls descriptor._ParseOptions using
974 // the given descriptor class name and serialized options protobuf string.
OptionsValue(const string & class_name,const string & serialized_options) const975 string Generator::OptionsValue(
976     const string& class_name, const string& serialized_options) const {
977   if (serialized_options.length() == 0 || GeneratingDescriptorProto()) {
978     return "None";
979   } else {
980     string full_class_name = "descriptor_pb2." + class_name;
981 //##!PY25    return "_descriptor._ParseOptions(" + full_class_name + "(), b'"
982 //##!PY25        + CEscape(serialized_options)+ "')";
983     return "_descriptor._ParseOptions(" + full_class_name + "(), _b('"  //##PY25
984         + CEscape(serialized_options)+ "'))";  //##PY25
985   }
986 }
987 
988 // Prints an expression for a Python FieldDescriptor for |field|.
PrintFieldDescriptor(const FieldDescriptor & field,bool is_extension) const989 void Generator::PrintFieldDescriptor(
990     const FieldDescriptor& field, bool is_extension) const {
991   string options_string;
992   field.options().SerializeToString(&options_string);
993   map<string, string> m;
994   m["name"] = field.name();
995   m["full_name"] = field.full_name();
996   m["index"] = SimpleItoa(field.index());
997   m["number"] = SimpleItoa(field.number());
998   m["type"] = SimpleItoa(field.type());
999   m["cpp_type"] = SimpleItoa(field.cpp_type());
1000   m["label"] = SimpleItoa(field.label());
1001   m["has_default_value"] = field.has_default_value() ? "True" : "False";
1002   m["default_value"] = StringifyDefaultValue(field);
1003   m["is_extension"] = is_extension ? "True" : "False";
1004   m["options"] = OptionsValue("FieldOptions", options_string);
1005   // We always set message_type and enum_type to None at this point, and then
1006   // these fields in correctly after all referenced descriptors have been
1007   // defined and/or imported (see FixForeignFieldsInDescriptors()).
1008   const char field_descriptor_decl[] =
1009     "_descriptor.FieldDescriptor(\n"
1010     "  name='$name$', full_name='$full_name$', index=$index$,\n"
1011     "  number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n"
1012     "  has_default_value=$has_default_value$, default_value=$default_value$,\n"
1013     "  message_type=None, enum_type=None, containing_type=None,\n"
1014     "  is_extension=$is_extension$, extension_scope=None,\n"
1015     "  options=$options$)";
1016   printer_->Print(m, field_descriptor_decl);
1017 }
1018 
1019 // Helper for Print{Fields,Extensions}InDescriptor().
PrintFieldDescriptorsInDescriptor(const Descriptor & message_descriptor,bool is_extension,const string & list_variable_name,int (Descriptor::* CountFn)()const,const FieldDescriptor * (Descriptor::* GetterFn)(int)const) const1020 void Generator::PrintFieldDescriptorsInDescriptor(
1021     const Descriptor& message_descriptor,
1022     bool is_extension,
1023     const string& list_variable_name,
1024     int (Descriptor::*CountFn)() const,
1025     const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const {
1026   printer_->Print("$list$=[\n", "list", list_variable_name);
1027   printer_->Indent();
1028   for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) {
1029     PrintFieldDescriptor(*(message_descriptor.*GetterFn)(i),
1030                          is_extension);
1031     printer_->Print(",\n");
1032   }
1033   printer_->Outdent();
1034   printer_->Print("],\n");
1035 }
1036 
1037 // Prints a statement assigning "fields" to a list of Python FieldDescriptors,
1038 // one for each field present in message_descriptor.
PrintFieldsInDescriptor(const Descriptor & message_descriptor) const1039 void Generator::PrintFieldsInDescriptor(
1040     const Descriptor& message_descriptor) const {
1041   const bool is_extension = false;
1042   PrintFieldDescriptorsInDescriptor(
1043       message_descriptor, is_extension, "fields",
1044       &Descriptor::field_count, &Descriptor::field);
1045 }
1046 
1047 // Prints a statement assigning "extensions" to a list of Python
1048 // FieldDescriptors, one for each extension present in message_descriptor.
PrintExtensionsInDescriptor(const Descriptor & message_descriptor) const1049 void Generator::PrintExtensionsInDescriptor(
1050     const Descriptor& message_descriptor) const {
1051   const bool is_extension = true;
1052   PrintFieldDescriptorsInDescriptor(
1053       message_descriptor, is_extension, "extensions",
1054       &Descriptor::extension_count, &Descriptor::extension);
1055 }
1056 
GeneratingDescriptorProto() const1057 bool Generator::GeneratingDescriptorProto() const {
1058   return file_->name() == "google/protobuf/descriptor.proto";
1059 }
1060 
1061 // Returns the unique Python module-level identifier given to a descriptor.
1062 // This name is module-qualified iff the given descriptor describes an
1063 // entity that doesn't come from the current file.
1064 template <typename DescriptorT>
ModuleLevelDescriptorName(const DescriptorT & descriptor) const1065 string Generator::ModuleLevelDescriptorName(
1066     const DescriptorT& descriptor) const {
1067   // FIXME(robinson):
1068   // We currently don't worry about collisions with underscores in the type
1069   // names, so these would collide in nasty ways if found in the same file:
1070   //   OuterProto.ProtoA.ProtoB
1071   //   OuterProto_ProtoA.ProtoB  # Underscore instead of period.
1072   // As would these:
1073   //   OuterProto.ProtoA_.ProtoB
1074   //   OuterProto.ProtoA._ProtoB  # Leading vs. trailing underscore.
1075   // (Contrived, but certainly possible).
1076   //
1077   // The C++ implementation doesn't guard against this either.  Leaving
1078   // it for now...
1079   string name = NamePrefixedWithNestedTypes(descriptor, "_");
1080   UpperString(&name);
1081   // Module-private for now.  Easy to make public later; almost impossible
1082   // to make private later.
1083   name = "_" + name;
1084   // We now have the name relative to its own module.  Also qualify with
1085   // the module name iff this descriptor is from a different .proto file.
1086   if (descriptor.file() != file_) {
1087     name = ModuleName(descriptor.file()->name()) + "." + name;
1088   }
1089   return name;
1090 }
1091 
1092 // Returns the name of the message class itself, not the descriptor.
1093 // Like ModuleLevelDescriptorName(), module-qualifies the name iff
1094 // the given descriptor describes an entity that doesn't come from
1095 // the current file.
ModuleLevelMessageName(const Descriptor & descriptor) const1096 string Generator::ModuleLevelMessageName(const Descriptor& descriptor) const {
1097   string name = NamePrefixedWithNestedTypes(descriptor, ".");
1098   if (descriptor.file() != file_) {
1099     name = ModuleName(descriptor.file()->name()) + "." + name;
1100   }
1101   return name;
1102 }
1103 
1104 // Returns the unique Python module-level identifier given to a service
1105 // descriptor.
ModuleLevelServiceDescriptorName(const ServiceDescriptor & descriptor) const1106 string Generator::ModuleLevelServiceDescriptorName(
1107     const ServiceDescriptor& descriptor) const {
1108   string name = descriptor.name();
1109   UpperString(&name);
1110   name = "_" + name;
1111   if (descriptor.file() != file_) {
1112     name = ModuleName(descriptor.file()->name()) + "." + name;
1113   }
1114   return name;
1115 }
1116 
1117 // Prints standard constructor arguments serialized_start and serialized_end.
1118 // Args:
1119 //   descriptor: The cpp descriptor to have a serialized reference.
1120 //   proto: A proto
1121 // Example printer output:
1122 // serialized_start=41,
1123 // serialized_end=43,
1124 //
1125 template <typename DescriptorT, typename DescriptorProtoT>
PrintSerializedPbInterval(const DescriptorT & descriptor,DescriptorProtoT & proto) const1126 void Generator::PrintSerializedPbInterval(
1127     const DescriptorT& descriptor, DescriptorProtoT& proto) const {
1128   descriptor.CopyTo(&proto);
1129   string sp;
1130   proto.SerializeToString(&sp);
1131   int offset = file_descriptor_serialized_.find(sp);
1132   GOOGLE_CHECK_GE(offset, 0);
1133 
1134   printer_->Print("serialized_start=$serialized_start$,\n"
1135                   "serialized_end=$serialized_end$,\n",
1136                   "serialized_start", SimpleItoa(offset),
1137                   "serialized_end", SimpleItoa(offset + sp.size()));
1138 }
1139 
1140 namespace {
PrintDescriptorOptionsFixingCode(const string & descriptor,const string & options,io::Printer * printer)1141 void PrintDescriptorOptionsFixingCode(const string& descriptor,
1142                                       const string& options,
1143                                       io::Printer* printer) {
1144   // TODO(xiaofeng): I have added a method _SetOptions() to DescriptorBase
1145   // in proto2 python runtime but it couldn't be used here because appengine
1146   // uses a snapshot version of the library in which the new method is not
1147   // yet present. After appengine has synced their runtime library, the code
1148   // below should be cleaned up to use _SetOptions().
1149   printer->Print(
1150       "$descriptor$.has_options = True\n"
1151       "$descriptor$._options = $options$\n",
1152       "descriptor", descriptor, "options", options);
1153 }
1154 }  // namespace
1155 
1156 // Prints expressions that set the options field of all descriptors.
FixAllDescriptorOptions() const1157 void Generator::FixAllDescriptorOptions() const {
1158   // Prints an expression that sets the file descriptor's options.
1159   string file_options = OptionsValue(
1160       "FileOptions", file_->options().SerializeAsString());
1161   if (file_options != "None") {
1162     PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_);
1163   }
1164   // Prints expressions that set the options for all top level enums.
1165   for (int i = 0; i < file_->enum_type_count(); ++i) {
1166     const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
1167     FixOptionsForEnum(enum_descriptor);
1168   }
1169   // Prints expressions that set the options for all top level extensions.
1170   for (int i = 0; i < file_->extension_count(); ++i) {
1171     const FieldDescriptor& field = *file_->extension(i);
1172     FixOptionsForField(field);
1173   }
1174   // Prints expressions that set the options for all messages, nested enums,
1175   // nested extensions and message fields.
1176   for (int i = 0; i < file_->message_type_count(); ++i) {
1177     FixOptionsForMessage(*file_->message_type(i));
1178   }
1179 }
1180 
1181 // Prints expressions that set the options for an enum descriptor and its
1182 // value descriptors.
FixOptionsForEnum(const EnumDescriptor & enum_descriptor) const1183 void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const {
1184   string descriptor_name = ModuleLevelDescriptorName(enum_descriptor);
1185   string enum_options = OptionsValue(
1186       "EnumOptions", enum_descriptor.options().SerializeAsString());
1187   if (enum_options != "None") {
1188     PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_);
1189   }
1190   for (int i = 0; i < enum_descriptor.value_count(); ++i) {
1191     const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i);
1192     string value_options = OptionsValue(
1193         "EnumValueOptions", value_descriptor.options().SerializeAsString());
1194     if (value_options != "None") {
1195       PrintDescriptorOptionsFixingCode(
1196           StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(),
1197                        value_descriptor.name().c_str()),
1198           value_options, printer_);
1199     }
1200   }
1201 }
1202 
1203 // Prints expressions that set the options for field descriptors (including
1204 // extensions).
FixOptionsForField(const FieldDescriptor & field) const1205 void Generator::FixOptionsForField(
1206     const FieldDescriptor& field) const {
1207   string field_options = OptionsValue(
1208       "FieldOptions", field.options().SerializeAsString());
1209   if (field_options != "None") {
1210     string field_name;
1211     if (field.is_extension()) {
1212       if (field.extension_scope() == NULL) {
1213         // Top level extensions.
1214         field_name = field.name();
1215       } else {
1216         field_name = FieldReferencingExpression(
1217             field.extension_scope(), field, "extensions_by_name");
1218       }
1219     } else {
1220       field_name = FieldReferencingExpression(
1221           field.containing_type(), field, "fields_by_name");
1222     }
1223     PrintDescriptorOptionsFixingCode(field_name, field_options, printer_);
1224   }
1225 }
1226 
1227 // Prints expressions that set the options for a message and all its inner
1228 // types (nested messages, nested enums, extensions, fields).
FixOptionsForMessage(const Descriptor & descriptor) const1229 void Generator::FixOptionsForMessage(const Descriptor& descriptor) const {
1230   // Nested messages.
1231   for (int i = 0; i < descriptor.nested_type_count(); ++i) {
1232     FixOptionsForMessage(*descriptor.nested_type(i));
1233   }
1234   // Enums.
1235   for (int i = 0; i < descriptor.enum_type_count(); ++i) {
1236     FixOptionsForEnum(*descriptor.enum_type(i));
1237   }
1238   // Fields.
1239   for (int i = 0; i < descriptor.field_count(); ++i) {
1240     const FieldDescriptor& field = *descriptor.field(i);
1241     FixOptionsForField(field);
1242   }
1243   // Extensions.
1244   for (int i = 0; i < descriptor.extension_count(); ++i) {
1245     const FieldDescriptor& field = *descriptor.extension(i);
1246     FixOptionsForField(field);
1247   }
1248   // Message option for this message.
1249   string message_options = OptionsValue(
1250       "MessageOptions", descriptor.options().SerializeAsString());
1251   if (message_options != "None") {
1252     string descriptor_name = ModuleLevelDescriptorName(descriptor);
1253     PrintDescriptorOptionsFixingCode(descriptor_name,
1254                                      message_options,
1255                                      printer_);
1256   }
1257 }
1258 
1259 }  // namespace python
1260 }  // namespace compiler
1261 }  // namespace protobuf
1262 }  // namespace google
1263