OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 26 matching lines...) Expand all Loading... |
37 // In other words, our job is basically to output a Python equivalent | 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 | 38 // of the C++ *Descriptor objects, and fix up all circular references |
39 // within these objects. | 39 // within these objects. |
40 // | 40 // |
41 // Note that the runtime performance of protocol message classes created in | 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 | 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 | 43 // generator that outputs a Python/C extension module that lets |
44 // performance-minded Python code leverage the fast C++ implementation | 44 // performance-minded Python code leverage the fast C++ implementation |
45 // directly. | 45 // directly. |
46 | 46 |
| 47 #include <algorithm> |
47 #include <google/protobuf/stubs/hash.h> | 48 #include <google/protobuf/stubs/hash.h> |
48 #include <limits> | 49 #include <limits> |
49 #include <map> | 50 #include <map> |
50 #include <memory> | 51 #include <memory> |
51 #ifndef _SHARED_PTR_H | 52 #ifndef _SHARED_PTR_H |
52 #include <google/protobuf/stubs/shared_ptr.h> | 53 #include <google/protobuf/stubs/shared_ptr.h> |
53 #endif | 54 #endif |
54 #include <string> | 55 #include <string> |
55 #include <utility> | 56 #include <utility> |
56 #include <vector> | 57 #include <vector> |
(...skipping 23 matching lines...) Expand all Loading... |
80 string StripProto(const string& filename) { | 81 string StripProto(const string& filename) { |
81 const char* suffix = HasSuffixString(filename, ".protodevel") | 82 const char* suffix = HasSuffixString(filename, ".protodevel") |
82 ? ".protodevel" : ".proto"; | 83 ? ".protodevel" : ".proto"; |
83 return StripSuffixString(filename, suffix); | 84 return StripSuffixString(filename, suffix); |
84 } | 85 } |
85 | 86 |
86 | 87 |
87 // Returns the Python module name expected for a given .proto filename. | 88 // Returns the Python module name expected for a given .proto filename. |
88 string ModuleName(const string& filename) { | 89 string ModuleName(const string& filename) { |
89 string basename = StripProto(filename); | 90 string basename = StripProto(filename); |
90 StripString(&basename, "-", '_'); | 91 ReplaceCharacters(&basename, "-", '_'); |
91 StripString(&basename, "/", '.'); | 92 ReplaceCharacters(&basename, "/", '.'); |
92 return basename + "_pb2"; | 93 return basename + "_pb2"; |
93 } | 94 } |
94 | 95 |
95 | 96 |
96 // Returns the alias we assign to the module of the given .proto filename | 97 // Returns the alias we assign to the module of the given .proto filename |
97 // when importing. See testPackageInitializationImport in | 98 // when importing. See testPackageInitializationImport in |
98 // google/protobuf/python/reflection_test.py | 99 // google/protobuf/python/reflection_test.py |
99 // to see why we need the alias. | 100 // to see why we need the alias. |
100 string ModuleAlias(const string& filename) { | 101 string ModuleAlias(const string& filename) { |
101 string module_name = ModuleName(filename); | 102 string module_name = ModuleName(filename); |
102 // We can't have dots in the module name, so we replace each with _dot_. | 103 // We can't have dots in the module name, so we replace each with _dot_. |
103 // But that could lead to a collision between a.b and a_dot_b, so we also | 104 // But that could lead to a collision between a.b and a_dot_b, so we also |
104 // duplicate each underscore. | 105 // duplicate each underscore. |
105 GlobalReplaceSubstring("_", "__", &module_name); | 106 GlobalReplaceSubstring("_", "__", &module_name); |
106 GlobalReplaceSubstring(".", "_dot_", &module_name); | 107 GlobalReplaceSubstring(".", "_dot_", &module_name); |
107 return module_name; | 108 return module_name; |
108 } | 109 } |
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])); |
110 | 121 |
111 // Returns an import statement of form "from X.Y.Z import T" for the given | 122 bool ContainsPythonKeyword(const string& module_name) { |
112 // .proto filename. | 123 std::vector<string> tokens = Split(module_name, "."); |
113 string ModuleImportStatement(const string& filename) { | 124 for (int i = 0; i < tokens.size(); ++i) { |
114 string module_name = ModuleName(filename); | 125 if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) { |
115 int last_dot_pos = module_name.rfind('.'); | 126 return true; |
116 if (last_dot_pos == string::npos) { | 127 } |
117 // NOTE(petya): this is not tested as it would require a protocol buffer | |
118 // outside of any package, and I don't think that is easily achievable. | |
119 return "import " + module_name; | |
120 } else { | |
121 return "from " + module_name.substr(0, last_dot_pos) + " import " + | |
122 module_name.substr(last_dot_pos + 1); | |
123 } | 128 } |
| 129 return false; |
124 } | 130 } |
125 | 131 |
126 | 132 |
127 // Returns the name of all containing types for descriptor, | 133 // Returns the name of all containing types for descriptor, |
128 // in order from outermost to innermost, followed by descriptor's | 134 // in order from outermost to innermost, followed by descriptor's |
129 // own name. Each name is separated by |separator|. | 135 // own name. Each name is separated by |separator|. |
130 template <typename DescriptorT> | 136 template <typename DescriptorT> |
131 string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, | 137 string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, |
132 const string& separator) { | 138 const string& separator) { |
133 string name = descriptor.name(); | 139 string name = descriptor.name(); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 case FieldDescriptor::CPPTYPE_INT32: | 223 case FieldDescriptor::CPPTYPE_INT32: |
218 return SimpleItoa(field.default_value_int32()); | 224 return SimpleItoa(field.default_value_int32()); |
219 case FieldDescriptor::CPPTYPE_UINT32: | 225 case FieldDescriptor::CPPTYPE_UINT32: |
220 return SimpleItoa(field.default_value_uint32()); | 226 return SimpleItoa(field.default_value_uint32()); |
221 case FieldDescriptor::CPPTYPE_INT64: | 227 case FieldDescriptor::CPPTYPE_INT64: |
222 return SimpleItoa(field.default_value_int64()); | 228 return SimpleItoa(field.default_value_int64()); |
223 case FieldDescriptor::CPPTYPE_UINT64: | 229 case FieldDescriptor::CPPTYPE_UINT64: |
224 return SimpleItoa(field.default_value_uint64()); | 230 return SimpleItoa(field.default_value_uint64()); |
225 case FieldDescriptor::CPPTYPE_DOUBLE: { | 231 case FieldDescriptor::CPPTYPE_DOUBLE: { |
226 double value = field.default_value_double(); | 232 double value = field.default_value_double(); |
227 if (value == numeric_limits<double>::infinity()) { | 233 if (value == std::numeric_limits<double>::infinity()) { |
228 // Python pre-2.6 on Windows does not parse "inf" correctly. However, | 234 // Python pre-2.6 on Windows does not parse "inf" correctly. However, |
229 // a numeric literal that is too big for a double will become infinity. | 235 // a numeric literal that is too big for a double will become infinity. |
230 return "1e10000"; | 236 return "1e10000"; |
231 } else if (value == -numeric_limits<double>::infinity()) { | 237 } else if (value == -std::numeric_limits<double>::infinity()) { |
232 // See above. | 238 // See above. |
233 return "-1e10000"; | 239 return "-1e10000"; |
234 } else if (value != value) { | 240 } else if (value != value) { |
235 // infinity * 0 = nan | 241 // infinity * 0 = nan |
236 return "(1e10000 * 0)"; | 242 return "(1e10000 * 0)"; |
237 } else { | 243 } else { |
238 return "float(" + SimpleDtoa(value) + ")"; | 244 return "float(" + SimpleDtoa(value) + ")"; |
239 } | 245 } |
240 } | 246 } |
241 case FieldDescriptor::CPPTYPE_FLOAT: { | 247 case FieldDescriptor::CPPTYPE_FLOAT: { |
242 float value = field.default_value_float(); | 248 float value = field.default_value_float(); |
243 if (value == numeric_limits<float>::infinity()) { | 249 if (value == std::numeric_limits<float>::infinity()) { |
244 // Python pre-2.6 on Windows does not parse "inf" correctly. However, | 250 // Python pre-2.6 on Windows does not parse "inf" correctly. However, |
245 // a numeric literal that is too big for a double will become infinity. | 251 // a numeric literal that is too big for a double will become infinity. |
246 return "1e10000"; | 252 return "1e10000"; |
247 } else if (value == -numeric_limits<float>::infinity()) { | 253 } else if (value == -std::numeric_limits<float>::infinity()) { |
248 // See above. | 254 // See above. |
249 return "-1e10000"; | 255 return "-1e10000"; |
250 } else if (value != value) { | 256 } else if (value != value) { |
251 // infinity - infinity = nan | 257 // infinity - infinity = nan |
252 return "(1e10000 * 0)"; | 258 return "(1e10000 * 0)"; |
253 } else { | 259 } else { |
254 return "float(" + SimpleFtoa(value) + ")"; | 260 return "float(" + SimpleFtoa(value) + ")"; |
255 } | 261 } |
256 } | 262 } |
257 case FieldDescriptor::CPPTYPE_BOOL: | 263 case FieldDescriptor::CPPTYPE_BOOL: |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 // thread-safety constraints of the CodeGenerator interface aren't clear so | 313 // thread-safety constraints of the CodeGenerator interface aren't clear so |
308 // just be as conservative as possible. It's easier to relax this later if | 314 // just be as conservative as possible. It's easier to relax this later if |
309 // we need to, but I doubt it will be an issue. | 315 // we need to, but I doubt it will be an issue. |
310 // TODO(kenton): The proper thing to do would be to allocate any state on | 316 // TODO(kenton): The proper thing to do would be to allocate any state on |
311 // the stack and use that, so that the Generator class itself does not need | 317 // the stack and use that, so that the Generator class itself does not need |
312 // to have any mutable members. Then it is implicitly thread-safe. | 318 // to have any mutable members. Then it is implicitly thread-safe. |
313 MutexLock lock(&mutex_); | 319 MutexLock lock(&mutex_); |
314 file_ = file; | 320 file_ = file; |
315 string module_name = ModuleName(file->name()); | 321 string module_name = ModuleName(file->name()); |
316 string filename = module_name; | 322 string filename = module_name; |
317 StripString(&filename, ".", '/'); | 323 ReplaceCharacters(&filename, ".", '/'); |
318 filename += ".py"; | 324 filename += ".py"; |
319 | 325 |
320 FileDescriptorProto fdp; | 326 FileDescriptorProto fdp; |
321 file_->CopyTo(&fdp); | 327 file_->CopyTo(&fdp); |
322 fdp.SerializeToString(&file_descriptor_serialized_); | 328 fdp.SerializeToString(&file_descriptor_serialized_); |
323 | 329 |
324 | 330 |
325 google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(fi
lename)); | 331 google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(fi
lename)); |
326 GOOGLE_CHECK(output.get()); | 332 GOOGLE_CHECK(output.get()); |
327 io::Printer printer(output.get(), '$'); | 333 io::Printer printer(output.get(), '$'); |
(...skipping 24 matching lines...) Expand all Loading... |
352 printer.Print( | 358 printer.Print( |
353 "# @@protoc_insertion_point(module_scope)\n"); | 359 "# @@protoc_insertion_point(module_scope)\n"); |
354 | 360 |
355 return !printer.failed(); | 361 return !printer.failed(); |
356 } | 362 } |
357 | 363 |
358 // Prints Python imports for all modules imported by |file|. | 364 // Prints Python imports for all modules imported by |file|. |
359 void Generator::PrintImports() const { | 365 void Generator::PrintImports() const { |
360 for (int i = 0; i < file_->dependency_count(); ++i) { | 366 for (int i = 0; i < file_->dependency_count(); ++i) { |
361 const string& filename = file_->dependency(i)->name(); | 367 const string& filename = file_->dependency(i)->name(); |
362 string import_statement = ModuleImportStatement(filename); | 368 |
| 369 string module_name = ModuleName(filename); |
363 string module_alias = ModuleAlias(filename); | 370 string module_alias = ModuleAlias(filename); |
364 printer_->Print("$statement$ as $alias$\n", "statement", | 371 if (ContainsPythonKeyword(module_name)) { |
365 import_statement, "alias", module_alias); | 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 |
366 CopyPublicDependenciesAliases(module_alias, file_->dependency(i)); | 394 CopyPublicDependenciesAliases(module_alias, file_->dependency(i)); |
367 } | 395 } |
368 printer_->Print("\n"); | 396 printer_->Print("\n"); |
369 | 397 |
370 // Print public imports. | 398 // Print public imports. |
371 for (int i = 0; i < file_->public_dependency_count(); ++i) { | 399 for (int i = 0; i < file_->public_dependency_count(); ++i) { |
372 string module_name = ModuleName(file_->public_dependency(i)->name()); | 400 string module_name = ModuleName(file_->public_dependency(i)->name()); |
373 printer_->Print("from $module$ import *\n", "module", module_name); | 401 printer_->Print("from $module$ import *\n", "module", module_name); |
374 } | 402 } |
375 printer_->Print("\n"); | 403 printer_->Print("\n"); |
376 } | 404 } |
377 | 405 |
378 // Prints the single file descriptor for this file. | 406 // Prints the single file descriptor for this file. |
379 void Generator::PrintFileDescriptor() const { | 407 void Generator::PrintFileDescriptor() const { |
380 map<string, string> m; | 408 std::map<string, string> m; |
381 m["descriptor_name"] = kDescriptorKey; | 409 m["descriptor_name"] = kDescriptorKey; |
382 m["name"] = file_->name(); | 410 m["name"] = file_->name(); |
383 m["package"] = file_->package(); | 411 m["package"] = file_->package(); |
384 m["syntax"] = StringifySyntax(file_->syntax()); | 412 m["syntax"] = StringifySyntax(file_->syntax()); |
385 const char file_descriptor_template[] = | 413 const char file_descriptor_template[] = |
386 "$descriptor_name$ = _descriptor.FileDescriptor(\n" | 414 "$descriptor_name$ = _descriptor.FileDescriptor(\n" |
387 " name='$name$',\n" | 415 " name='$name$',\n" |
388 " package='$package$',\n" | 416 " package='$package$',\n" |
389 " syntax='$syntax$',\n"; | 417 " syntax='$syntax$',\n"; |
390 printer_->Print(m, file_descriptor_template); | 418 printer_->Print(m, file_descriptor_template); |
391 printer_->Indent(); | 419 printer_->Indent(); |
392 printer_->Print( | 420 printer_->Print( |
393 //##!PY25 "serialized_pb=b'$value$'\n", | 421 //##!PY25 "serialized_pb=b'$value$'\n", |
394 "serialized_pb=_b('$value$')\n", //##PY25 | 422 "serialized_pb=_b('$value$')\n", //##PY25 |
395 "value", strings::CHexEscape(file_descriptor_serialized_)); | 423 "value", strings::CHexEscape(file_descriptor_serialized_)); |
396 if (file_->dependency_count() != 0) { | 424 if (file_->dependency_count() != 0) { |
397 printer_->Print(",\ndependencies=["); | 425 printer_->Print(",\ndependencies=["); |
398 for (int i = 0; i < file_->dependency_count(); ++i) { | 426 for (int i = 0; i < file_->dependency_count(); ++i) { |
399 string module_alias = ModuleAlias(file_->dependency(i)->name()); | 427 string module_alias = ModuleAlias(file_->dependency(i)->name()); |
400 printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias", | 428 printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias", |
401 module_alias); | 429 module_alias); |
402 } | 430 } |
403 printer_->Print("]"); | 431 printer_->Print("]"); |
404 } | 432 } |
| 433 if (file_->public_dependency_count() > 0) { |
| 434 printer_->Print(",\npublic_dependencies=["); |
| 435 for (int i = 0; i < file_->public_dependency_count(); ++i) { |
| 436 string module_alias = ModuleAlias(file_->public_dependency(i)->name()); |
| 437 printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias", |
| 438 module_alias); |
| 439 } |
| 440 printer_->Print("]"); |
| 441 } |
405 | 442 |
406 // TODO(falk): Also print options and fix the message_type, enum_type, | 443 // TODO(falk): Also print options and fix the message_type, enum_type, |
407 // service and extension later in the generation. | 444 // service and extension later in the generation. |
408 | 445 |
409 printer_->Outdent(); | 446 printer_->Outdent(); |
410 printer_->Print(")\n"); | 447 printer_->Print(")\n"); |
411 printer_->Print("_sym_db.RegisterFileDescriptor($name$)\n", "name", | 448 printer_->Print("_sym_db.RegisterFileDescriptor($name$)\n", "name", |
412 kDescriptorKey); | 449 kDescriptorKey); |
413 printer_->Print("\n"); | 450 printer_->Print("\n"); |
414 } | 451 } |
415 | 452 |
416 // Prints descriptors and module-level constants for all top-level | 453 // Prints descriptors and module-level constants for all top-level |
417 // enums defined in |file|. | 454 // enums defined in |file|. |
418 void Generator::PrintTopLevelEnums() const { | 455 void Generator::PrintTopLevelEnums() const { |
419 vector<pair<string, int> > top_level_enum_values; | 456 std::vector<std::pair<string, int> > top_level_enum_values; |
420 for (int i = 0; i < file_->enum_type_count(); ++i) { | 457 for (int i = 0; i < file_->enum_type_count(); ++i) { |
421 const EnumDescriptor& enum_descriptor = *file_->enum_type(i); | 458 const EnumDescriptor& enum_descriptor = *file_->enum_type(i); |
422 PrintEnum(enum_descriptor); | 459 PrintEnum(enum_descriptor); |
423 printer_->Print("$name$ = " | 460 printer_->Print("$name$ = " |
424 "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)", | 461 "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)", |
425 "name", enum_descriptor.name(), | 462 "name", enum_descriptor.name(), |
426 "descriptor_name", | 463 "descriptor_name", |
427 ModuleLevelDescriptorName(enum_descriptor)); | 464 ModuleLevelDescriptorName(enum_descriptor)); |
428 printer_->Print("\n"); | 465 printer_->Print("\n"); |
429 | 466 |
(...skipping 16 matching lines...) Expand all Loading... |
446 void Generator::PrintAllNestedEnumsInFile() const { | 483 void Generator::PrintAllNestedEnumsInFile() const { |
447 for (int i = 0; i < file_->message_type_count(); ++i) { | 484 for (int i = 0; i < file_->message_type_count(); ++i) { |
448 PrintNestedEnums(*file_->message_type(i)); | 485 PrintNestedEnums(*file_->message_type(i)); |
449 } | 486 } |
450 } | 487 } |
451 | 488 |
452 // Prints a Python statement assigning the appropriate module-level | 489 // Prints a Python statement assigning the appropriate module-level |
453 // enum name to a Python EnumDescriptor object equivalent to | 490 // enum name to a Python EnumDescriptor object equivalent to |
454 // enum_descriptor. | 491 // enum_descriptor. |
455 void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { | 492 void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { |
456 map<string, string> m; | 493 std::map<string, string> m; |
457 string module_level_descriptor_name = | 494 string module_level_descriptor_name = |
458 ModuleLevelDescriptorName(enum_descriptor); | 495 ModuleLevelDescriptorName(enum_descriptor); |
459 m["descriptor_name"] = module_level_descriptor_name; | 496 m["descriptor_name"] = module_level_descriptor_name; |
460 m["name"] = enum_descriptor.name(); | 497 m["name"] = enum_descriptor.name(); |
461 m["full_name"] = enum_descriptor.full_name(); | 498 m["full_name"] = enum_descriptor.full_name(); |
462 m["file"] = kDescriptorKey; | 499 m["file"] = kDescriptorKey; |
463 const char enum_descriptor_template[] = | 500 const char enum_descriptor_template[] = |
464 "$descriptor_name$ = _descriptor.EnumDescriptor(\n" | 501 "$descriptor_name$ = _descriptor.EnumDescriptor(\n" |
465 " name='$name$',\n" | 502 " name='$name$',\n" |
466 " full_name='$full_name$',\n" | 503 " full_name='$full_name$',\n" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 const ServiceDescriptor& descriptor) const { | 577 const ServiceDescriptor& descriptor) const { |
541 printer_->Print("\n"); | 578 printer_->Print("\n"); |
542 string service_name = ModuleLevelServiceDescriptorName(descriptor); | 579 string service_name = ModuleLevelServiceDescriptorName(descriptor); |
543 string options_string; | 580 string options_string; |
544 descriptor.options().SerializeToString(&options_string); | 581 descriptor.options().SerializeToString(&options_string); |
545 | 582 |
546 printer_->Print( | 583 printer_->Print( |
547 "$service_name$ = _descriptor.ServiceDescriptor(\n", | 584 "$service_name$ = _descriptor.ServiceDescriptor(\n", |
548 "service_name", service_name); | 585 "service_name", service_name); |
549 printer_->Indent(); | 586 printer_->Indent(); |
550 map<string, string> m; | 587 std::map<string, string> m; |
551 m["name"] = descriptor.name(); | 588 m["name"] = descriptor.name(); |
552 m["full_name"] = descriptor.full_name(); | 589 m["full_name"] = descriptor.full_name(); |
553 m["file"] = kDescriptorKey; | 590 m["file"] = kDescriptorKey; |
554 m["index"] = SimpleItoa(descriptor.index()); | 591 m["index"] = SimpleItoa(descriptor.index()); |
555 m["options_value"] = OptionsValue("ServiceOptions", options_string); | 592 m["options_value"] = OptionsValue("ServiceOptions", options_string); |
556 const char required_function_arguments[] = | 593 const char required_function_arguments[] = |
557 "name='$name$',\n" | 594 "name='$name$',\n" |
558 "full_name='$full_name$',\n" | 595 "full_name='$full_name$',\n" |
559 "file=$file$,\n" | 596 "file=$file$,\n" |
560 "index=$index$,\n" | 597 "index=$index$,\n" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 // | 673 // |
637 // Mutually recursive with PrintNestedDescriptors(). | 674 // Mutually recursive with PrintNestedDescriptors(). |
638 void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { | 675 void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { |
639 PrintNestedDescriptors(message_descriptor); | 676 PrintNestedDescriptors(message_descriptor); |
640 | 677 |
641 printer_->Print("\n"); | 678 printer_->Print("\n"); |
642 printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n", | 679 printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n", |
643 "descriptor_name", | 680 "descriptor_name", |
644 ModuleLevelDescriptorName(message_descriptor)); | 681 ModuleLevelDescriptorName(message_descriptor)); |
645 printer_->Indent(); | 682 printer_->Indent(); |
646 map<string, string> m; | 683 std::map<string, string> m; |
647 m["name"] = message_descriptor.name(); | 684 m["name"] = message_descriptor.name(); |
648 m["full_name"] = message_descriptor.full_name(); | 685 m["full_name"] = message_descriptor.full_name(); |
649 m["file"] = kDescriptorKey; | 686 m["file"] = kDescriptorKey; |
650 const char required_function_arguments[] = | 687 const char required_function_arguments[] = |
651 "name='$name$',\n" | 688 "name='$name$',\n" |
652 "full_name='$full_name$',\n" | 689 "full_name='$full_name$',\n" |
653 "filename=None,\n" | 690 "filename=None,\n" |
654 "file=$file$,\n" | 691 "file=$file$,\n" |
655 "containing_type=None,\n"; | 692 "containing_type=None,\n"; |
656 printer_->Print(m, required_function_arguments); | 693 printer_->Print(m, required_function_arguments); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 message_descriptor.extension_range(i); | 733 message_descriptor.extension_range(i); |
697 printer_->Print("($start$, $end$), ", | 734 printer_->Print("($start$, $end$), ", |
698 "start", SimpleItoa(range->start), | 735 "start", SimpleItoa(range->start), |
699 "end", SimpleItoa(range->end)); | 736 "end", SimpleItoa(range->end)); |
700 } | 737 } |
701 printer_->Print("],\n"); | 738 printer_->Print("],\n"); |
702 printer_->Print("oneofs=[\n"); | 739 printer_->Print("oneofs=[\n"); |
703 printer_->Indent(); | 740 printer_->Indent(); |
704 for (int i = 0; i < message_descriptor.oneof_decl_count(); ++i) { | 741 for (int i = 0; i < message_descriptor.oneof_decl_count(); ++i) { |
705 const OneofDescriptor* desc = message_descriptor.oneof_decl(i); | 742 const OneofDescriptor* desc = message_descriptor.oneof_decl(i); |
706 map<string, string> m; | 743 std::map<string, string> m; |
707 m["name"] = desc->name(); | 744 m["name"] = desc->name(); |
708 m["full_name"] = desc->full_name(); | 745 m["full_name"] = desc->full_name(); |
709 m["index"] = SimpleItoa(desc->index()); | 746 m["index"] = SimpleItoa(desc->index()); |
| 747 string options_string = |
| 748 OptionsValue("OneofOptions", desc->options().SerializeAsString()); |
| 749 if (options_string == "None") { |
| 750 m["options"] = ""; |
| 751 } else { |
| 752 m["options"] = ", options=" + options_string; |
| 753 } |
710 printer_->Print( | 754 printer_->Print( |
711 m, | 755 m, |
712 "_descriptor.OneofDescriptor(\n" | 756 "_descriptor.OneofDescriptor(\n" |
713 " name='$name$', full_name='$full_name$',\n" | 757 " name='$name$', full_name='$full_name$',\n" |
714 " index=$index$, containing_type=None, fields=[]),\n"); | 758 " index=$index$, containing_type=None, fields=[]$options$),\n"); |
715 } | 759 } |
716 printer_->Outdent(); | 760 printer_->Outdent(); |
717 printer_->Print("],\n"); | 761 printer_->Print("],\n"); |
718 // Serialization of proto | 762 // Serialization of proto |
719 DescriptorProto edp; | 763 DescriptorProto edp; |
720 PrintSerializedPbInterval(message_descriptor, edp); | 764 PrintSerializedPbInterval(message_descriptor, edp); |
721 | 765 |
722 printer_->Outdent(); | 766 printer_->Outdent(); |
723 printer_->Print(")\n"); | 767 printer_->Print(")\n"); |
724 } | 768 } |
725 | 769 |
726 // Prints Python Descriptor objects for all nested types contained in | 770 // Prints Python Descriptor objects for all nested types contained in |
727 // message_descriptor. | 771 // message_descriptor. |
728 // | 772 // |
729 // Mutually recursive with PrintDescriptor(). | 773 // Mutually recursive with PrintDescriptor(). |
730 void Generator::PrintNestedDescriptors( | 774 void Generator::PrintNestedDescriptors( |
731 const Descriptor& containing_descriptor) const { | 775 const Descriptor& containing_descriptor) const { |
732 for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { | 776 for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { |
733 PrintDescriptor(*containing_descriptor.nested_type(i)); | 777 PrintDescriptor(*containing_descriptor.nested_type(i)); |
734 } | 778 } |
735 } | 779 } |
736 | 780 |
737 // Prints all messages in |file|. | 781 // Prints all messages in |file|. |
738 void Generator::PrintMessages() const { | 782 void Generator::PrintMessages() const { |
739 for (int i = 0; i < file_->message_type_count(); ++i) { | 783 for (int i = 0; i < file_->message_type_count(); ++i) { |
740 vector<string> to_register; | 784 std::vector<string> to_register; |
741 PrintMessage(*file_->message_type(i), "", &to_register); | 785 PrintMessage(*file_->message_type(i), "", &to_register); |
742 for (int j = 0; j < to_register.size(); ++j) { | 786 for (int j = 0; j < to_register.size(); ++j) { |
743 printer_->Print("_sym_db.RegisterMessage($name$)\n", "name", | 787 printer_->Print("_sym_db.RegisterMessage($name$)\n", "name", |
744 to_register[j]); | 788 to_register[j]); |
745 } | 789 } |
746 printer_->Print("\n"); | 790 printer_->Print("\n"); |
747 } | 791 } |
748 } | 792 } |
749 | 793 |
750 // Prints a Python class for the given message descriptor. We defer to the | 794 // Prints a Python class for the given message descriptor. We defer to the |
751 // metaclass to do almost all of the work of actually creating a useful class. | 795 // metaclass to do almost all of the work of actually creating a useful class. |
752 // The purpose of this function and its many helper functions above is merely | 796 // The purpose of this function and its many helper functions above is merely |
753 // to output a Python version of the descriptors, which the metaclass in | 797 // to output a Python version of the descriptors, which the metaclass in |
754 // reflection.py will use to construct the meat of the class itself. | 798 // reflection.py will use to construct the meat of the class itself. |
755 // | 799 // |
756 // Mutually recursive with PrintNestedMessages(). | 800 // Mutually recursive with PrintNestedMessages(). |
757 // Collect nested message names to_register for the symbol_database. | 801 // Collect nested message names to_register for the symbol_database. |
758 void Generator::PrintMessage(const Descriptor& message_descriptor, | 802 void Generator::PrintMessage(const Descriptor& message_descriptor, |
759 const string& prefix, | 803 const string& prefix, |
760 vector<string>* to_register) const { | 804 std::vector<string>* to_register) const { |
761 string qualified_name(prefix + message_descriptor.name()); | 805 string qualified_name(prefix + message_descriptor.name()); |
762 to_register->push_back(qualified_name); | 806 to_register->push_back(qualified_name); |
763 printer_->Print( | 807 printer_->Print( |
764 "$name$ = _reflection.GeneratedProtocolMessageType('$name$', " | 808 "$name$ = _reflection.GeneratedProtocolMessageType('$name$', " |
765 "(_message.Message,), dict(\n", | 809 "(_message.Message,), dict(\n", |
766 "name", message_descriptor.name()); | 810 "name", message_descriptor.name()); |
767 printer_->Indent(); | 811 printer_->Indent(); |
768 | 812 |
769 PrintNestedMessages(message_descriptor, qualified_name + ".", to_register); | 813 PrintNestedMessages(message_descriptor, qualified_name + ".", to_register); |
770 map<string, string> m; | 814 std::map<string, string> m; |
771 m["descriptor_key"] = kDescriptorKey; | 815 m["descriptor_key"] = kDescriptorKey; |
772 m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor); | 816 m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor); |
773 printer_->Print(m, "$descriptor_key$ = $descriptor_name$,\n"); | 817 printer_->Print(m, "$descriptor_key$ = $descriptor_name$,\n"); |
774 printer_->Print("__module__ = '$module_name$'\n", | 818 printer_->Print("__module__ = '$module_name$'\n", |
775 "module_name", ModuleName(file_->name())); | 819 "module_name", ModuleName(file_->name())); |
776 printer_->Print("# @@protoc_insertion_point(class_scope:$full_name$)\n", | 820 printer_->Print("# @@protoc_insertion_point(class_scope:$full_name$)\n", |
777 "full_name", message_descriptor.full_name()); | 821 "full_name", message_descriptor.full_name()); |
778 printer_->Print("))\n"); | 822 printer_->Print("))\n"); |
779 printer_->Outdent(); | 823 printer_->Outdent(); |
780 } | 824 } |
781 | 825 |
782 // Prints all nested messages within |containing_descriptor|. | 826 // Prints all nested messages within |containing_descriptor|. |
783 // Mutually recursive with PrintMessage(). | 827 // Mutually recursive with PrintMessage(). |
784 void Generator::PrintNestedMessages(const Descriptor& containing_descriptor, | 828 void Generator::PrintNestedMessages(const Descriptor& containing_descriptor, |
785 const string& prefix, | 829 const string& prefix, |
786 vector<string>* to_register) const { | 830 std::vector<string>* to_register) const { |
787 for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { | 831 for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { |
788 printer_->Print("\n"); | 832 printer_->Print("\n"); |
789 PrintMessage(*containing_descriptor.nested_type(i), prefix, to_register); | 833 PrintMessage(*containing_descriptor.nested_type(i), prefix, to_register); |
790 printer_->Print(",\n"); | 834 printer_->Print(",\n"); |
791 } | 835 } |
792 } | 836 } |
793 | 837 |
794 // Recursively fixes foreign fields in all nested types in |descriptor|, then | 838 // Recursively fixes foreign fields in all nested types in |descriptor|, then |
795 // sets the message_type and enum_type of all message and enum fields to point | 839 // sets the message_type and enum_type of all message and enum fields to point |
796 // to their respective descriptors. | 840 // to their respective descriptors. |
(...skipping 12 matching lines...) Expand all Loading... |
809 const FieldDescriptor& field_descriptor = *descriptor.field(i); | 853 const FieldDescriptor& field_descriptor = *descriptor.field(i); |
810 FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name"); | 854 FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name"); |
811 } | 855 } |
812 | 856 |
813 FixContainingTypeInDescriptor(descriptor, containing_descriptor); | 857 FixContainingTypeInDescriptor(descriptor, containing_descriptor); |
814 for (int i = 0; i < descriptor.enum_type_count(); ++i) { | 858 for (int i = 0; i < descriptor.enum_type_count(); ++i) { |
815 const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i); | 859 const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i); |
816 FixContainingTypeInDescriptor(enum_descriptor, &descriptor); | 860 FixContainingTypeInDescriptor(enum_descriptor, &descriptor); |
817 } | 861 } |
818 for (int i = 0; i < descriptor.oneof_decl_count(); ++i) { | 862 for (int i = 0; i < descriptor.oneof_decl_count(); ++i) { |
819 map<string, string> m; | 863 std::map<string, string> m; |
820 const OneofDescriptor* oneof = descriptor.oneof_decl(i); | 864 const OneofDescriptor* oneof = descriptor.oneof_decl(i); |
821 m["descriptor_name"] = ModuleLevelDescriptorName(descriptor); | 865 m["descriptor_name"] = ModuleLevelDescriptorName(descriptor); |
822 m["oneof_name"] = oneof->name(); | 866 m["oneof_name"] = oneof->name(); |
823 for (int j = 0; j < oneof->field_count(); ++j) { | 867 for (int j = 0; j < oneof->field_count(); ++j) { |
824 m["field_name"] = oneof->field(j)->name(); | 868 m["field_name"] = oneof->field(j)->name(); |
825 printer_->Print( | 869 printer_->Print( |
826 m, | 870 m, |
827 "$descriptor_name$.oneofs_by_name['$oneof_name$'].fields.append(\n" | 871 "$descriptor_name$.oneofs_by_name['$oneof_name$'].fields.append(\n" |
828 " $descriptor_name$.fields_by_name['$field_name$'])\n"); | 872 " $descriptor_name$.fields_by_name['$field_name$'])\n"); |
829 printer_->Print( | 873 printer_->Print( |
830 m, | 874 m, |
831 "$descriptor_name$.fields_by_name['$field_name$'].containing_oneof = " | 875 "$descriptor_name$.fields_by_name['$field_name$'].containing_oneof = " |
832 "$descriptor_name$.oneofs_by_name['$oneof_name$']\n"); | 876 "$descriptor_name$.oneofs_by_name['$oneof_name$']\n"); |
833 } | 877 } |
834 } | 878 } |
835 } | 879 } |
836 | 880 |
837 void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const { | 881 void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const { |
838 map<string, string> m; | 882 std::map<string, string> m; |
839 m["descriptor_name"] = kDescriptorKey; | 883 m["descriptor_name"] = kDescriptorKey; |
840 m["message_name"] = descriptor.name(); | 884 m["message_name"] = descriptor.name(); |
841 m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor); | 885 m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor); |
842 const char file_descriptor_template[] = | 886 const char file_descriptor_template[] = |
843 "$descriptor_name$.message_types_by_name['$message_name$'] = " | 887 "$descriptor_name$.message_types_by_name['$message_name$'] = " |
844 "$message_descriptor_name$\n"; | 888 "$message_descriptor_name$\n"; |
845 printer_->Print(m, file_descriptor_template); | 889 printer_->Print(m, file_descriptor_template); |
846 } | 890 } |
847 | 891 |
848 void Generator::AddEnumToFileDescriptor( | 892 void Generator::AddEnumToFileDescriptor( |
849 const EnumDescriptor& descriptor) const { | 893 const EnumDescriptor& descriptor) const { |
850 map<string, string> m; | 894 std::map<string, string> m; |
851 m["descriptor_name"] = kDescriptorKey; | 895 m["descriptor_name"] = kDescriptorKey; |
852 m["enum_name"] = descriptor.name(); | 896 m["enum_name"] = descriptor.name(); |
853 m["enum_descriptor_name"] = ModuleLevelDescriptorName(descriptor); | 897 m["enum_descriptor_name"] = ModuleLevelDescriptorName(descriptor); |
854 const char file_descriptor_template[] = | 898 const char file_descriptor_template[] = |
855 "$descriptor_name$.enum_types_by_name['$enum_name$'] = " | 899 "$descriptor_name$.enum_types_by_name['$enum_name$'] = " |
856 "$enum_descriptor_name$\n"; | 900 "$enum_descriptor_name$\n"; |
857 printer_->Print(m, file_descriptor_template); | 901 printer_->Print(m, file_descriptor_template); |
858 } | 902 } |
859 | 903 |
860 void Generator::AddExtensionToFileDescriptor( | 904 void Generator::AddExtensionToFileDescriptor( |
861 const FieldDescriptor& descriptor) const { | 905 const FieldDescriptor& descriptor) const { |
862 map<string, string> m; | 906 std::map<string, string> m; |
863 m["descriptor_name"] = kDescriptorKey; | 907 m["descriptor_name"] = kDescriptorKey; |
864 m["field_name"] = descriptor.name(); | 908 m["field_name"] = descriptor.name(); |
865 const char file_descriptor_template[] = | 909 const char file_descriptor_template[] = |
866 "$descriptor_name$.extensions_by_name['$field_name$'] = " | 910 "$descriptor_name$.extensions_by_name['$field_name$'] = " |
867 "$field_name$\n"; | 911 "$field_name$\n"; |
868 printer_->Print(m, file_descriptor_template); | 912 printer_->Print(m, file_descriptor_template); |
869 } | 913 } |
870 | 914 |
871 // Sets any necessary message_type and enum_type attributes | 915 // Sets any necessary message_type and enum_type attributes |
872 // for the Python version of |field|. | 916 // for the Python version of |field|. |
873 // | 917 // |
874 // containing_type may be NULL, in which case this is a module-level field. | 918 // containing_type may be NULL, in which case this is a module-level field. |
875 // | 919 // |
876 // python_dict_name is the name of the Python dict where we should | 920 // python_dict_name is the name of the Python dict where we should |
877 // look the field up in the containing type. (e.g., fields_by_name | 921 // look the field up in the containing type. (e.g., fields_by_name |
878 // or extensions_by_name). We ignore python_dict_name if containing_type | 922 // or extensions_by_name). We ignore python_dict_name if containing_type |
879 // is NULL. | 923 // is NULL. |
880 void Generator::FixForeignFieldsInField(const Descriptor* containing_type, | 924 void Generator::FixForeignFieldsInField(const Descriptor* containing_type, |
881 const FieldDescriptor& field, | 925 const FieldDescriptor& field, |
882 const string& python_dict_name) const { | 926 const string& python_dict_name) const { |
883 const string field_referencing_expression = FieldReferencingExpression( | 927 const string field_referencing_expression = FieldReferencingExpression( |
884 containing_type, field, python_dict_name); | 928 containing_type, field, python_dict_name); |
885 map<string, string> m; | 929 std::map<string, string> m; |
886 m["field_ref"] = field_referencing_expression; | 930 m["field_ref"] = field_referencing_expression; |
887 const Descriptor* foreign_message_type = field.message_type(); | 931 const Descriptor* foreign_message_type = field.message_type(); |
888 if (foreign_message_type) { | 932 if (foreign_message_type) { |
889 m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type); | 933 m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type); |
890 printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n"); | 934 printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n"); |
891 } | 935 } |
892 const EnumDescriptor* enum_type = field.enum_type(); | 936 const EnumDescriptor* enum_type = field.enum_type(); |
893 if (enum_type) { | 937 if (enum_type) { |
894 m["enum_type"] = ModuleLevelDescriptorName(*enum_type); | 938 m["enum_type"] = ModuleLevelDescriptorName(*enum_type); |
895 printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n"); | 939 printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n"); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 } | 1018 } |
975 | 1019 |
976 void Generator::FixForeignFieldsInExtension( | 1020 void Generator::FixForeignFieldsInExtension( |
977 const FieldDescriptor& extension_field) const { | 1021 const FieldDescriptor& extension_field) const { |
978 GOOGLE_CHECK(extension_field.is_extension()); | 1022 GOOGLE_CHECK(extension_field.is_extension()); |
979 // extension_scope() will be NULL for top-level extensions, which is | 1023 // extension_scope() will be NULL for top-level extensions, which is |
980 // exactly what FixForeignFieldsInField() wants. | 1024 // exactly what FixForeignFieldsInField() wants. |
981 FixForeignFieldsInField(extension_field.extension_scope(), extension_field, | 1025 FixForeignFieldsInField(extension_field.extension_scope(), extension_field, |
982 "extensions_by_name"); | 1026 "extensions_by_name"); |
983 | 1027 |
984 map<string, string> m; | 1028 std::map<string, string> m; |
985 // Confusingly, for FieldDescriptors that happen to be extensions, | 1029 // Confusingly, for FieldDescriptors that happen to be extensions, |
986 // containing_type() means "extended type." | 1030 // containing_type() means "extended type." |
987 // On the other hand, extension_scope() will give us what we normally | 1031 // On the other hand, extension_scope() will give us what we normally |
988 // mean by containing_type(). | 1032 // mean by containing_type(). |
989 m["extended_message_class"] = ModuleLevelMessageName( | 1033 m["extended_message_class"] = ModuleLevelMessageName( |
990 *extension_field.containing_type()); | 1034 *extension_field.containing_type()); |
991 m["field"] = FieldReferencingExpression(extension_field.extension_scope(), | 1035 m["field"] = FieldReferencingExpression(extension_field.extension_scope(), |
992 extension_field, | 1036 extension_field, |
993 "extensions_by_name"); | 1037 "extensions_by_name"); |
994 printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n"); | 1038 printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n"); |
(...skipping 12 matching lines...) Expand all Loading... |
1007 } | 1051 } |
1008 | 1052 |
1009 // Returns a Python expression that instantiates a Python EnumValueDescriptor | 1053 // Returns a Python expression that instantiates a Python EnumValueDescriptor |
1010 // object for the given C++ descriptor. | 1054 // object for the given C++ descriptor. |
1011 void Generator::PrintEnumValueDescriptor( | 1055 void Generator::PrintEnumValueDescriptor( |
1012 const EnumValueDescriptor& descriptor) const { | 1056 const EnumValueDescriptor& descriptor) const { |
1013 // TODO(robinson): Fix up EnumValueDescriptor "type" fields. | 1057 // TODO(robinson): Fix up EnumValueDescriptor "type" fields. |
1014 // More circular references. ::sigh:: | 1058 // More circular references. ::sigh:: |
1015 string options_string; | 1059 string options_string; |
1016 descriptor.options().SerializeToString(&options_string); | 1060 descriptor.options().SerializeToString(&options_string); |
1017 map<string, string> m; | 1061 std::map<string, string> m; |
1018 m["name"] = descriptor.name(); | 1062 m["name"] = descriptor.name(); |
1019 m["index"] = SimpleItoa(descriptor.index()); | 1063 m["index"] = SimpleItoa(descriptor.index()); |
1020 m["number"] = SimpleItoa(descriptor.number()); | 1064 m["number"] = SimpleItoa(descriptor.number()); |
1021 m["options"] = OptionsValue("EnumValueOptions", options_string); | 1065 m["options"] = OptionsValue("EnumValueOptions", options_string); |
1022 printer_->Print( | 1066 printer_->Print( |
1023 m, | 1067 m, |
1024 "_descriptor.EnumValueDescriptor(\n" | 1068 "_descriptor.EnumValueDescriptor(\n" |
1025 " name='$name$', index=$index$, number=$number$,\n" | 1069 " name='$name$', index=$index$, number=$number$,\n" |
1026 " options=$options$,\n" | 1070 " options=$options$,\n" |
1027 " type=None)"); | 1071 " type=None)"); |
(...skipping 12 matching lines...) Expand all Loading... |
1040 return "_descriptor._ParseOptions(" + full_class_name + "(), _b('" //##PY25 | 1084 return "_descriptor._ParseOptions(" + full_class_name + "(), _b('" //##PY25 |
1041 + CEscape(serialized_options)+ "'))"; //##PY25 | 1085 + CEscape(serialized_options)+ "'))"; //##PY25 |
1042 } | 1086 } |
1043 } | 1087 } |
1044 | 1088 |
1045 // Prints an expression for a Python FieldDescriptor for |field|. | 1089 // Prints an expression for a Python FieldDescriptor for |field|. |
1046 void Generator::PrintFieldDescriptor( | 1090 void Generator::PrintFieldDescriptor( |
1047 const FieldDescriptor& field, bool is_extension) const { | 1091 const FieldDescriptor& field, bool is_extension) const { |
1048 string options_string; | 1092 string options_string; |
1049 field.options().SerializeToString(&options_string); | 1093 field.options().SerializeToString(&options_string); |
1050 map<string, string> m; | 1094 std::map<string, string> m; |
1051 m["name"] = field.name(); | 1095 m["name"] = field.name(); |
1052 m["full_name"] = field.full_name(); | 1096 m["full_name"] = field.full_name(); |
1053 m["index"] = SimpleItoa(field.index()); | 1097 m["index"] = SimpleItoa(field.index()); |
1054 m["number"] = SimpleItoa(field.number()); | 1098 m["number"] = SimpleItoa(field.number()); |
1055 m["type"] = SimpleItoa(field.type()); | 1099 m["type"] = SimpleItoa(field.type()); |
1056 m["cpp_type"] = SimpleItoa(field.cpp_type()); | 1100 m["cpp_type"] = SimpleItoa(field.cpp_type()); |
1057 m["label"] = SimpleItoa(field.label()); | 1101 m["label"] = SimpleItoa(field.label()); |
1058 m["has_default_value"] = field.has_default_value() ? "True" : "False"; | 1102 m["has_default_value"] = field.has_default_value() ? "True" : "False"; |
1059 m["default_value"] = StringifyDefaultValue(field); | 1103 m["default_value"] = StringifyDefaultValue(field); |
1060 m["is_extension"] = is_extension ? "True" : "False"; | 1104 m["is_extension"] = is_extension ? "True" : "False"; |
1061 m["options"] = OptionsValue("FieldOptions", options_string); | 1105 m["options"] = OptionsValue("FieldOptions", options_string); |
| 1106 m["json_name"] = field.has_json_name() ? |
| 1107 ", json_name='" + field.json_name() + "'": ""; |
1062 // We always set message_type and enum_type to None at this point, and then | 1108 // We always set message_type and enum_type to None at this point, and then |
1063 // these fields in correctly after all referenced descriptors have been | 1109 // these fields in correctly after all referenced descriptors have been |
1064 // defined and/or imported (see FixForeignFieldsInDescriptors()). | 1110 // defined and/or imported (see FixForeignFieldsInDescriptors()). |
1065 const char field_descriptor_decl[] = | 1111 const char field_descriptor_decl[] = |
1066 "_descriptor.FieldDescriptor(\n" | 1112 "_descriptor.FieldDescriptor(\n" |
1067 " name='$name$', full_name='$full_name$', index=$index$,\n" | 1113 " name='$name$', full_name='$full_name$', index=$index$,\n" |
1068 " number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n" | 1114 " number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n" |
1069 " has_default_value=$has_default_value$, default_value=$default_value$,\n" | 1115 " has_default_value=$has_default_value$, default_value=$default_value$,\n" |
1070 " message_type=None, enum_type=None, containing_type=None,\n" | 1116 " message_type=None, enum_type=None, containing_type=None,\n" |
1071 " is_extension=$is_extension$, extension_scope=None,\n" | 1117 " is_extension=$is_extension$, extension_scope=None,\n" |
1072 " options=$options$)"; | 1118 " options=$options$$json_name$)"; |
1073 printer_->Print(m, field_descriptor_decl); | 1119 printer_->Print(m, field_descriptor_decl); |
1074 } | 1120 } |
1075 | 1121 |
1076 // Helper for Print{Fields,Extensions}InDescriptor(). | 1122 // Helper for Print{Fields,Extensions}InDescriptor(). |
1077 void Generator::PrintFieldDescriptorsInDescriptor( | 1123 void Generator::PrintFieldDescriptorsInDescriptor( |
1078 const Descriptor& message_descriptor, | 1124 const Descriptor& message_descriptor, |
1079 bool is_extension, | 1125 bool is_extension, |
1080 const string& list_variable_name, | 1126 const string& list_variable_name, |
1081 int (Descriptor::*CountFn)() const, | 1127 int (Descriptor::*CountFn)() const, |
1082 const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const { | 1128 const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const { |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1228 const FieldDescriptor& field = *file_->extension(i); | 1274 const FieldDescriptor& field = *file_->extension(i); |
1229 FixOptionsForField(field); | 1275 FixOptionsForField(field); |
1230 } | 1276 } |
1231 // Prints expressions that set the options for all messages, nested enums, | 1277 // Prints expressions that set the options for all messages, nested enums, |
1232 // nested extensions and message fields. | 1278 // nested extensions and message fields. |
1233 for (int i = 0; i < file_->message_type_count(); ++i) { | 1279 for (int i = 0; i < file_->message_type_count(); ++i) { |
1234 FixOptionsForMessage(*file_->message_type(i)); | 1280 FixOptionsForMessage(*file_->message_type(i)); |
1235 } | 1281 } |
1236 } | 1282 } |
1237 | 1283 |
| 1284 void Generator::FixOptionsForOneof(const OneofDescriptor& oneof) const { |
| 1285 string oneof_options = OptionsValue( |
| 1286 "OneofOptions", oneof.options().SerializeAsString()); |
| 1287 if (oneof_options != "None") { |
| 1288 string oneof_name = strings::Substitute( |
| 1289 "$0.$1['$2']", |
| 1290 ModuleLevelDescriptorName(*oneof.containing_type()), |
| 1291 "oneofs_by_name", oneof.name()); |
| 1292 PrintDescriptorOptionsFixingCode(oneof_name, oneof_options, printer_); |
| 1293 } |
| 1294 } |
| 1295 |
1238 // Prints expressions that set the options for an enum descriptor and its | 1296 // Prints expressions that set the options for an enum descriptor and its |
1239 // value descriptors. | 1297 // value descriptors. |
1240 void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const { | 1298 void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const { |
1241 string descriptor_name = ModuleLevelDescriptorName(enum_descriptor); | 1299 string descriptor_name = ModuleLevelDescriptorName(enum_descriptor); |
1242 string enum_options = OptionsValue( | 1300 string enum_options = OptionsValue( |
1243 "EnumOptions", enum_descriptor.options().SerializeAsString()); | 1301 "EnumOptions", enum_descriptor.options().SerializeAsString()); |
1244 if (enum_options != "None") { | 1302 if (enum_options != "None") { |
1245 PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_); | 1303 PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_); |
1246 } | 1304 } |
1247 for (int i = 0; i < enum_descriptor.value_count(); ++i) { | 1305 for (int i = 0; i < enum_descriptor.value_count(); ++i) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1281 } | 1339 } |
1282 } | 1340 } |
1283 | 1341 |
1284 // Prints expressions that set the options for a message and all its inner | 1342 // Prints expressions that set the options for a message and all its inner |
1285 // types (nested messages, nested enums, extensions, fields). | 1343 // types (nested messages, nested enums, extensions, fields). |
1286 void Generator::FixOptionsForMessage(const Descriptor& descriptor) const { | 1344 void Generator::FixOptionsForMessage(const Descriptor& descriptor) const { |
1287 // Nested messages. | 1345 // Nested messages. |
1288 for (int i = 0; i < descriptor.nested_type_count(); ++i) { | 1346 for (int i = 0; i < descriptor.nested_type_count(); ++i) { |
1289 FixOptionsForMessage(*descriptor.nested_type(i)); | 1347 FixOptionsForMessage(*descriptor.nested_type(i)); |
1290 } | 1348 } |
| 1349 // Oneofs. |
| 1350 for (int i = 0; i < descriptor.oneof_decl_count(); ++i) { |
| 1351 FixOptionsForOneof(*descriptor.oneof_decl(i)); |
| 1352 } |
1291 // Enums. | 1353 // Enums. |
1292 for (int i = 0; i < descriptor.enum_type_count(); ++i) { | 1354 for (int i = 0; i < descriptor.enum_type_count(); ++i) { |
1293 FixOptionsForEnum(*descriptor.enum_type(i)); | 1355 FixOptionsForEnum(*descriptor.enum_type(i)); |
1294 } | 1356 } |
1295 // Fields. | 1357 // Fields. |
1296 for (int i = 0; i < descriptor.field_count(); ++i) { | 1358 for (int i = 0; i < descriptor.field_count(); ++i) { |
1297 const FieldDescriptor& field = *descriptor.field(i); | 1359 const FieldDescriptor& field = *descriptor.field(i); |
1298 FixOptionsForField(field); | 1360 FixOptionsForField(field); |
1299 } | 1361 } |
1300 // Extensions. | 1362 // Extensions. |
(...skipping 21 matching lines...) Expand all Loading... |
1322 printer_->Print("$alias$ = $copy_from$.$alias$\n", "alias", module_alias, | 1384 printer_->Print("$alias$ = $copy_from$.$alias$\n", "alias", module_alias, |
1323 "copy_from", copy_from); | 1385 "copy_from", copy_from); |
1324 CopyPublicDependenciesAliases(copy_from, file->public_dependency(i)); | 1386 CopyPublicDependenciesAliases(copy_from, file->public_dependency(i)); |
1325 } | 1387 } |
1326 } | 1388 } |
1327 | 1389 |
1328 } // namespace python | 1390 } // namespace python |
1329 } // namespace compiler | 1391 } // namespace compiler |
1330 } // namespace protobuf | 1392 } // namespace protobuf |
1331 } // namespace google | 1393 } // namespace google |
OLD | NEW |