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