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