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