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