OLD | NEW |
1 # Protocol Buffers - Google's data interchange format | 1 # Protocol Buffers - Google's data interchange format |
2 # Copyright 2008 Google Inc. All rights reserved. | 2 # Copyright 2008 Google Inc. All rights reserved. |
3 # https://developers.google.com/protocol-buffers/ | 3 # https://developers.google.com/protocol-buffers/ |
4 # | 4 # |
5 # Redistribution and use in source and binary forms, with or without | 5 # Redistribution and use in source and binary forms, with or without |
6 # modification, are permitted provided that the following conditions are | 6 # modification, are permitted provided that the following conditions are |
7 # met: | 7 # met: |
8 # | 8 # |
9 # * Redistributions of source code must retain the above copyright | 9 # * Redistributions of source code must retain the above copyright |
10 # notice, this list of conditions and the following disclaimer. | 10 # notice, this list of conditions and the following disclaimer. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 module in order to create a protocol buffer class that can be encoded and | 50 module in order to create a protocol buffer class that can be encoded and |
51 decoded. | 51 decoded. |
52 | 52 |
53 If you want to get a Python class for the specified proto, use the | 53 If you want to get a Python class for the specified proto, use the |
54 helper functions inside google.protobuf.message_factory | 54 helper functions inside google.protobuf.message_factory |
55 directly instead of this class. | 55 directly instead of this class. |
56 """ | 56 """ |
57 | 57 |
58 __author__ = 'matthewtoia@google.com (Matt Toia)' | 58 __author__ = 'matthewtoia@google.com (Matt Toia)' |
59 | 59 |
| 60 import collections |
| 61 |
60 from google.protobuf import descriptor | 62 from google.protobuf import descriptor |
61 from google.protobuf import descriptor_database | 63 from google.protobuf import descriptor_database |
62 from google.protobuf import text_encoding | 64 from google.protobuf import text_encoding |
63 | 65 |
64 | 66 |
65 _USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS | 67 _USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS # pylint: disable=protected-
access |
66 | 68 |
67 | 69 |
68 def _NormalizeFullyQualifiedName(name): | 70 def _NormalizeFullyQualifiedName(name): |
69 """Remove leading period from fully-qualified type name. | 71 """Remove leading period from fully-qualified type name. |
70 | 72 |
71 Due to b/13860351 in descriptor_database.py, types in the root namespace are | 73 Due to b/13860351 in descriptor_database.py, types in the root namespace are |
72 generated with a leading period. This function removes that prefix. | 74 generated with a leading period. This function removes that prefix. |
73 | 75 |
74 Args: | 76 Args: |
75 name: A str, the fully-qualified symbol name. | 77 name: A str, the fully-qualified symbol name. |
76 | 78 |
77 Returns: | 79 Returns: |
78 A str, the normalized fully-qualified symbol name. | 80 A str, the normalized fully-qualified symbol name. |
79 """ | 81 """ |
80 return name.lstrip('.') | 82 return name.lstrip('.') |
81 | 83 |
82 | 84 |
| 85 def _OptionsOrNone(descriptor_proto): |
| 86 """Returns the value of the field `options`, or None if it is not set.""" |
| 87 if descriptor_proto.HasField('options'): |
| 88 return descriptor_proto.options |
| 89 else: |
| 90 return None |
| 91 |
| 92 |
| 93 def _IsMessageSetExtension(field): |
| 94 return (field.is_extension and |
| 95 field.containing_type.has_options and |
| 96 field.containing_type.GetOptions().message_set_wire_format and |
| 97 field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and |
| 98 field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL) |
| 99 |
| 100 |
83 class DescriptorPool(object): | 101 class DescriptorPool(object): |
84 """A collection of protobufs dynamically constructed by descriptor protos.""" | 102 """A collection of protobufs dynamically constructed by descriptor protos.""" |
85 | 103 |
86 if _USE_C_DESCRIPTORS: | 104 if _USE_C_DESCRIPTORS: |
87 | 105 |
88 def __new__(cls, descriptor_db=None): | 106 def __new__(cls, descriptor_db=None): |
89 # pylint: disable=protected-access | 107 # pylint: disable=protected-access |
90 return descriptor._message.DescriptorPool(descriptor_db) | 108 return descriptor._message.DescriptorPool(descriptor_db) |
91 | 109 |
92 def __init__(self, descriptor_db=None): | 110 def __init__(self, descriptor_db=None): |
93 """Initializes a Pool of proto buffs. | 111 """Initializes a Pool of proto buffs. |
94 | 112 |
95 The descriptor_db argument to the constructor is provided to allow | 113 The descriptor_db argument to the constructor is provided to allow |
96 specialized file descriptor proto lookup code to be triggered on demand. An | 114 specialized file descriptor proto lookup code to be triggered on demand. An |
97 example would be an implementation which will read and compile a file | 115 example would be an implementation which will read and compile a file |
98 specified in a call to FindFileByName() and not require the call to Add() | 116 specified in a call to FindFileByName() and not require the call to Add() |
99 at all. Results from this database will be cached internally here as well. | 117 at all. Results from this database will be cached internally here as well. |
100 | 118 |
101 Args: | 119 Args: |
102 descriptor_db: A secondary source of file descriptors. | 120 descriptor_db: A secondary source of file descriptors. |
103 """ | 121 """ |
104 | 122 |
105 self._internal_db = descriptor_database.DescriptorDatabase() | 123 self._internal_db = descriptor_database.DescriptorDatabase() |
106 self._descriptor_db = descriptor_db | 124 self._descriptor_db = descriptor_db |
107 self._descriptors = {} | 125 self._descriptors = {} |
108 self._enum_descriptors = {} | 126 self._enum_descriptors = {} |
109 self._file_descriptors = {} | 127 self._file_descriptors = {} |
| 128 self._toplevel_extensions = {} |
| 129 # We store extensions in two two-level mappings: The first key is the |
| 130 # descriptor of the message being extended, the second key is the extension |
| 131 # full name or its tag number. |
| 132 self._extensions_by_name = collections.defaultdict(dict) |
| 133 self._extensions_by_number = collections.defaultdict(dict) |
110 | 134 |
111 def Add(self, file_desc_proto): | 135 def Add(self, file_desc_proto): |
112 """Adds the FileDescriptorProto and its types to this pool. | 136 """Adds the FileDescriptorProto and its types to this pool. |
113 | 137 |
114 Args: | 138 Args: |
115 file_desc_proto: The FileDescriptorProto to add. | 139 file_desc_proto: The FileDescriptorProto to add. |
116 """ | 140 """ |
117 | 141 |
118 self._internal_db.Add(file_desc_proto) | 142 self._internal_db.Add(file_desc_proto) |
119 | 143 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 Args: | 179 Args: |
156 enum_desc: An EnumDescriptor. | 180 enum_desc: An EnumDescriptor. |
157 """ | 181 """ |
158 | 182 |
159 if not isinstance(enum_desc, descriptor.EnumDescriptor): | 183 if not isinstance(enum_desc, descriptor.EnumDescriptor): |
160 raise TypeError('Expected instance of descriptor.EnumDescriptor.') | 184 raise TypeError('Expected instance of descriptor.EnumDescriptor.') |
161 | 185 |
162 self._enum_descriptors[enum_desc.full_name] = enum_desc | 186 self._enum_descriptors[enum_desc.full_name] = enum_desc |
163 self.AddFileDescriptor(enum_desc.file) | 187 self.AddFileDescriptor(enum_desc.file) |
164 | 188 |
| 189 def AddExtensionDescriptor(self, extension): |
| 190 """Adds a FieldDescriptor describing an extension to the pool. |
| 191 |
| 192 Args: |
| 193 extension: A FieldDescriptor. |
| 194 |
| 195 Raises: |
| 196 AssertionError: when another extension with the same number extends the |
| 197 same message. |
| 198 TypeError: when the specified extension is not a |
| 199 descriptor.FieldDescriptor. |
| 200 """ |
| 201 if not (isinstance(extension, descriptor.FieldDescriptor) and |
| 202 extension.is_extension): |
| 203 raise TypeError('Expected an extension descriptor.') |
| 204 |
| 205 if extension.extension_scope is None: |
| 206 self._toplevel_extensions[extension.full_name] = extension |
| 207 |
| 208 try: |
| 209 existing_desc = self._extensions_by_number[ |
| 210 extension.containing_type][extension.number] |
| 211 except KeyError: |
| 212 pass |
| 213 else: |
| 214 if extension is not existing_desc: |
| 215 raise AssertionError( |
| 216 'Extensions "%s" and "%s" both try to extend message type "%s" ' |
| 217 'with field number %d.' % |
| 218 (extension.full_name, existing_desc.full_name, |
| 219 extension.containing_type.full_name, extension.number)) |
| 220 |
| 221 self._extensions_by_number[extension.containing_type][ |
| 222 extension.number] = extension |
| 223 self._extensions_by_name[extension.containing_type][ |
| 224 extension.full_name] = extension |
| 225 |
| 226 # Also register MessageSet extensions with the type name. |
| 227 if _IsMessageSetExtension(extension): |
| 228 self._extensions_by_name[extension.containing_type][ |
| 229 extension.message_type.full_name] = extension |
| 230 |
165 def AddFileDescriptor(self, file_desc): | 231 def AddFileDescriptor(self, file_desc): |
166 """Adds a FileDescriptor to the pool, non-recursively. | 232 """Adds a FileDescriptor to the pool, non-recursively. |
167 | 233 |
168 If the FileDescriptor contains messages or enums, the caller must explicitly | 234 If the FileDescriptor contains messages or enums, the caller must explicitly |
169 register them. | 235 register them. |
170 | 236 |
171 Args: | 237 Args: |
172 file_desc: A FileDescriptor. | 238 file_desc: A FileDescriptor. |
173 """ | 239 """ |
174 | 240 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 def FindExtensionByName(self, full_name): | 353 def FindExtensionByName(self, full_name): |
288 """Loads the named extension descriptor from the pool. | 354 """Loads the named extension descriptor from the pool. |
289 | 355 |
290 Args: | 356 Args: |
291 full_name: The full name of the extension descriptor to load. | 357 full_name: The full name of the extension descriptor to load. |
292 | 358 |
293 Returns: | 359 Returns: |
294 A FieldDescriptor, describing the named extension. | 360 A FieldDescriptor, describing the named extension. |
295 """ | 361 """ |
296 full_name = _NormalizeFullyQualifiedName(full_name) | 362 full_name = _NormalizeFullyQualifiedName(full_name) |
| 363 try: |
| 364 # The proto compiler does not give any link between the FileDescriptor |
| 365 # and top-level extensions unless the FileDescriptorProto is added to |
| 366 # the DescriptorDatabase, but this can impact memory usage. |
| 367 # So we registered these extensions by name explicitly. |
| 368 return self._toplevel_extensions[full_name] |
| 369 except KeyError: |
| 370 pass |
297 message_name, _, extension_name = full_name.rpartition('.') | 371 message_name, _, extension_name = full_name.rpartition('.') |
298 try: | 372 try: |
299 # Most extensions are nested inside a message. | 373 # Most extensions are nested inside a message. |
300 scope = self.FindMessageTypeByName(message_name) | 374 scope = self.FindMessageTypeByName(message_name) |
301 except KeyError: | 375 except KeyError: |
302 # Some extensions are defined at file scope. | 376 # Some extensions are defined at file scope. |
303 scope = self.FindFileContainingSymbol(full_name) | 377 scope = self.FindFileContainingSymbol(full_name) |
304 return scope.extensions_by_name[extension_name] | 378 return scope.extensions_by_name[extension_name] |
305 | 379 |
| 380 def FindExtensionByNumber(self, message_descriptor, number): |
| 381 """Gets the extension of the specified message with the specified number. |
| 382 |
| 383 Extensions have to be registered to this pool by calling |
| 384 AddExtensionDescriptor. |
| 385 |
| 386 Args: |
| 387 message_descriptor: descriptor of the extended message. |
| 388 number: integer, number of the extension field. |
| 389 |
| 390 Returns: |
| 391 A FieldDescriptor describing the extension. |
| 392 |
| 393 Raise: |
| 394 KeyError: when no extension with the given number is known for the |
| 395 specified message. |
| 396 """ |
| 397 return self._extensions_by_number[message_descriptor][number] |
| 398 |
| 399 def FindAllExtensions(self, message_descriptor): |
| 400 """Gets all the known extension of a given message. |
| 401 |
| 402 Extensions have to be registered to this pool by calling |
| 403 AddExtensionDescriptor. |
| 404 |
| 405 Args: |
| 406 message_descriptor: descriptor of the extended message. |
| 407 |
| 408 Returns: |
| 409 A list of FieldDescriptor describing the extensions. |
| 410 """ |
| 411 return list(self._extensions_by_number[message_descriptor].values()) |
| 412 |
306 def _ConvertFileProtoToFileDescriptor(self, file_proto): | 413 def _ConvertFileProtoToFileDescriptor(self, file_proto): |
307 """Creates a FileDescriptor from a proto or returns a cached copy. | 414 """Creates a FileDescriptor from a proto or returns a cached copy. |
308 | 415 |
309 This method also has the side effect of loading all the symbols found in | 416 This method also has the side effect of loading all the symbols found in |
310 the file into the appropriate dictionaries in the pool. | 417 the file into the appropriate dictionaries in the pool. |
311 | 418 |
312 Args: | 419 Args: |
313 file_proto: The proto to convert. | 420 file_proto: The proto to convert. |
314 | 421 |
315 Returns: | 422 Returns: |
316 A FileDescriptor matching the passed in proto. | 423 A FileDescriptor matching the passed in proto. |
317 """ | 424 """ |
318 | 425 |
319 if file_proto.name not in self._file_descriptors: | 426 if file_proto.name not in self._file_descriptors: |
320 built_deps = list(self._GetDeps(file_proto.dependency)) | 427 built_deps = list(self._GetDeps(file_proto.dependency)) |
321 direct_deps = [self.FindFileByName(n) for n in file_proto.dependency] | 428 direct_deps = [self.FindFileByName(n) for n in file_proto.dependency] |
322 public_deps = [direct_deps[i] for i in file_proto.public_dependency] | 429 public_deps = [direct_deps[i] for i in file_proto.public_dependency] |
323 | 430 |
324 file_descriptor = descriptor.FileDescriptor( | 431 file_descriptor = descriptor.FileDescriptor( |
325 pool=self, | 432 pool=self, |
326 name=file_proto.name, | 433 name=file_proto.name, |
327 package=file_proto.package, | 434 package=file_proto.package, |
328 syntax=file_proto.syntax, | 435 syntax=file_proto.syntax, |
329 options=file_proto.options, | 436 options=_OptionsOrNone(file_proto), |
330 serialized_pb=file_proto.SerializeToString(), | 437 serialized_pb=file_proto.SerializeToString(), |
331 dependencies=direct_deps, | 438 dependencies=direct_deps, |
332 public_dependencies=public_deps) | 439 public_dependencies=public_deps) |
333 if _USE_C_DESCRIPTORS: | 440 scope = {} |
334 # When using C++ descriptors, all objects defined in the file were added | 441 |
335 # to the C++ database when the FileDescriptor was built above. | 442 # This loop extracts all the message and enum types from all the |
336 # Just add them to this descriptor pool. | 443 # dependencies of the file_proto. This is necessary to create the |
337 def _AddMessageDescriptor(message_desc): | 444 # scope of available message types when defining the passed in |
338 self._descriptors[message_desc.full_name] = message_desc | 445 # file proto. |
339 for nested in message_desc.nested_types: | 446 for dependency in built_deps: |
340 _AddMessageDescriptor(nested) | 447 scope.update(self._ExtractSymbols( |
341 for enum_type in message_desc.enum_types: | 448 dependency.message_types_by_name.values())) |
342 _AddEnumDescriptor(enum_type) | 449 scope.update((_PrefixWithDot(enum.full_name), enum) |
343 def _AddEnumDescriptor(enum_desc): | 450 for enum in dependency.enum_types_by_name.values()) |
344 self._enum_descriptors[enum_desc.full_name] = enum_desc | 451 |
345 for message_type in file_descriptor.message_types_by_name.values(): | 452 for message_type in file_proto.message_type: |
346 _AddMessageDescriptor(message_type) | 453 message_desc = self._ConvertMessageDescriptor( |
347 for enum_type in file_descriptor.enum_types_by_name.values(): | 454 message_type, file_proto.package, file_descriptor, scope, |
348 _AddEnumDescriptor(enum_type) | 455 file_proto.syntax) |
| 456 file_descriptor.message_types_by_name[message_desc.name] = ( |
| 457 message_desc) |
| 458 |
| 459 for enum_type in file_proto.enum_type: |
| 460 file_descriptor.enum_types_by_name[enum_type.name] = ( |
| 461 self._ConvertEnumDescriptor(enum_type, file_proto.package, |
| 462 file_descriptor, None, scope)) |
| 463 |
| 464 for index, extension_proto in enumerate(file_proto.extension): |
| 465 extension_desc = self._MakeFieldDescriptor( |
| 466 extension_proto, file_proto.package, index, is_extension=True) |
| 467 extension_desc.containing_type = self._GetTypeFromScope( |
| 468 file_descriptor.package, extension_proto.extendee, scope) |
| 469 self._SetFieldType(extension_proto, extension_desc, |
| 470 file_descriptor.package, scope) |
| 471 file_descriptor.extensions_by_name[extension_desc.name] = ( |
| 472 extension_desc) |
| 473 |
| 474 for desc_proto in file_proto.message_type: |
| 475 self._SetAllFieldTypes(file_proto.package, desc_proto, scope) |
| 476 |
| 477 if file_proto.package: |
| 478 desc_proto_prefix = _PrefixWithDot(file_proto.package) |
349 else: | 479 else: |
350 scope = {} | 480 desc_proto_prefix = '' |
351 | 481 |
352 # This loop extracts all the message and enum types from all the | 482 for desc_proto in file_proto.message_type: |
353 # dependencies of the file_proto. This is necessary to create the | 483 desc = self._GetTypeFromScope( |
354 # scope of available message types when defining the passed in | 484 desc_proto_prefix, desc_proto.name, scope) |
355 # file proto. | 485 file_descriptor.message_types_by_name[desc_proto.name] = desc |
356 for dependency in built_deps: | |
357 scope.update(self._ExtractSymbols( | |
358 dependency.message_types_by_name.values())) | |
359 scope.update((_PrefixWithDot(enum.full_name), enum) | |
360 for enum in dependency.enum_types_by_name.values()) | |
361 | 486 |
362 for message_type in file_proto.message_type: | 487 for index, service_proto in enumerate(file_proto.service): |
363 message_desc = self._ConvertMessageDescriptor( | 488 file_descriptor.services_by_name[service_proto.name] = ( |
364 message_type, file_proto.package, file_descriptor, scope, | 489 self._MakeServiceDescriptor(service_proto, index, scope, |
365 file_proto.syntax) | 490 file_proto.package, file_descriptor)) |
366 file_descriptor.message_types_by_name[message_desc.name] = ( | |
367 message_desc) | |
368 | |
369 for enum_type in file_proto.enum_type: | |
370 file_descriptor.enum_types_by_name[enum_type.name] = ( | |
371 self._ConvertEnumDescriptor(enum_type, file_proto.package, | |
372 file_descriptor, None, scope)) | |
373 | |
374 for index, extension_proto in enumerate(file_proto.extension): | |
375 extension_desc = self._MakeFieldDescriptor( | |
376 extension_proto, file_proto.package, index, is_extension=True) | |
377 extension_desc.containing_type = self._GetTypeFromScope( | |
378 file_descriptor.package, extension_proto.extendee, scope) | |
379 self._SetFieldType(extension_proto, extension_desc, | |
380 file_descriptor.package, scope) | |
381 file_descriptor.extensions_by_name[extension_desc.name] = ( | |
382 extension_desc) | |
383 | |
384 for desc_proto in file_proto.message_type: | |
385 self._SetAllFieldTypes(file_proto.package, desc_proto, scope) | |
386 | |
387 if file_proto.package: | |
388 desc_proto_prefix = _PrefixWithDot(file_proto.package) | |
389 else: | |
390 desc_proto_prefix = '' | |
391 | |
392 for desc_proto in file_proto.message_type: | |
393 desc = self._GetTypeFromScope( | |
394 desc_proto_prefix, desc_proto.name, scope) | |
395 file_descriptor.message_types_by_name[desc_proto.name] = desc | |
396 | 491 |
397 self.Add(file_proto) | 492 self.Add(file_proto) |
398 self._file_descriptors[file_proto.name] = file_descriptor | 493 self._file_descriptors[file_proto.name] = file_descriptor |
399 | 494 |
400 return self._file_descriptors[file_proto.name] | 495 return self._file_descriptors[file_proto.name] |
401 | 496 |
402 def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None, | 497 def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None, |
403 scope=None, syntax=None): | 498 scope=None, syntax=None): |
404 """Adds the proto to the pool in the specified package. | 499 """Adds the proto to the pool in the specified package. |
405 | 500 |
406 Args: | 501 Args: |
407 desc_proto: The descriptor_pb2.DescriptorProto protobuf message. | 502 desc_proto: The descriptor_pb2.DescriptorProto protobuf message. |
408 package: The package the proto should be located in. | 503 package: The package the proto should be located in. |
409 file_desc: The file containing this message. | 504 file_desc: The file containing this message. |
410 scope: Dict mapping short and full symbols to message and enum types. | 505 scope: Dict mapping short and full symbols to message and enum types. |
| 506 syntax: string indicating syntax of the file ("proto2" or "proto3") |
411 | 507 |
412 Returns: | 508 Returns: |
413 The added descriptor. | 509 The added descriptor. |
414 """ | 510 """ |
415 | 511 |
416 if package: | 512 if package: |
417 desc_name = '.'.join((package, desc_proto.name)) | 513 desc_name = '.'.join((package, desc_proto.name)) |
418 else: | 514 else: |
419 desc_name = desc_proto.name | 515 desc_name = desc_proto.name |
420 | 516 |
(...skipping 13 matching lines...) Expand all Loading... |
434 self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope) | 530 self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope) |
435 for enum in desc_proto.enum_type] | 531 for enum in desc_proto.enum_type] |
436 fields = [self._MakeFieldDescriptor(field, desc_name, index) | 532 fields = [self._MakeFieldDescriptor(field, desc_name, index) |
437 for index, field in enumerate(desc_proto.field)] | 533 for index, field in enumerate(desc_proto.field)] |
438 extensions = [ | 534 extensions = [ |
439 self._MakeFieldDescriptor(extension, desc_name, index, | 535 self._MakeFieldDescriptor(extension, desc_name, index, |
440 is_extension=True) | 536 is_extension=True) |
441 for index, extension in enumerate(desc_proto.extension)] | 537 for index, extension in enumerate(desc_proto.extension)] |
442 oneofs = [ | 538 oneofs = [ |
443 descriptor.OneofDescriptor(desc.name, '.'.join((desc_name, desc.name)), | 539 descriptor.OneofDescriptor(desc.name, '.'.join((desc_name, desc.name)), |
444 index, None, []) | 540 index, None, [], desc.options) |
445 for index, desc in enumerate(desc_proto.oneof_decl)] | 541 for index, desc in enumerate(desc_proto.oneof_decl)] |
446 extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range] | 542 extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range] |
447 if extension_ranges: | 543 if extension_ranges: |
448 is_extendable = True | 544 is_extendable = True |
449 else: | 545 else: |
450 is_extendable = False | 546 is_extendable = False |
451 desc = descriptor.Descriptor( | 547 desc = descriptor.Descriptor( |
452 name=desc_proto.name, | 548 name=desc_proto.name, |
453 full_name=desc_name, | 549 full_name=desc_name, |
454 filename=file_name, | 550 filename=file_name, |
455 containing_type=None, | 551 containing_type=None, |
456 fields=fields, | 552 fields=fields, |
457 oneofs=oneofs, | 553 oneofs=oneofs, |
458 nested_types=nested, | 554 nested_types=nested, |
459 enum_types=enums, | 555 enum_types=enums, |
460 extensions=extensions, | 556 extensions=extensions, |
461 options=desc_proto.options, | 557 options=_OptionsOrNone(desc_proto), |
462 is_extendable=is_extendable, | 558 is_extendable=is_extendable, |
463 extension_ranges=extension_ranges, | 559 extension_ranges=extension_ranges, |
464 file=file_desc, | 560 file=file_desc, |
465 serialized_start=None, | 561 serialized_start=None, |
466 serialized_end=None, | 562 serialized_end=None, |
467 syntax=syntax) | 563 syntax=syntax) |
468 for nested in desc.nested_types: | 564 for nested in desc.nested_types: |
469 nested.containing_type = desc | 565 nested.containing_type = desc |
470 for enum in desc.enum_types: | 566 for enum in desc.enum_types: |
471 enum.containing_type = desc | 567 enum.containing_type = desc |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 file_name = file_desc.name | 601 file_name = file_desc.name |
506 | 602 |
507 values = [self._MakeEnumValueDescriptor(value, index) | 603 values = [self._MakeEnumValueDescriptor(value, index) |
508 for index, value in enumerate(enum_proto.value)] | 604 for index, value in enumerate(enum_proto.value)] |
509 desc = descriptor.EnumDescriptor(name=enum_proto.name, | 605 desc = descriptor.EnumDescriptor(name=enum_proto.name, |
510 full_name=enum_name, | 606 full_name=enum_name, |
511 filename=file_name, | 607 filename=file_name, |
512 file=file_desc, | 608 file=file_desc, |
513 values=values, | 609 values=values, |
514 containing_type=containing_type, | 610 containing_type=containing_type, |
515 options=enum_proto.options) | 611 options=_OptionsOrNone(enum_proto)) |
516 scope['.%s' % enum_name] = desc | 612 scope['.%s' % enum_name] = desc |
517 self._enum_descriptors[enum_name] = desc | 613 self._enum_descriptors[enum_name] = desc |
518 return desc | 614 return desc |
519 | 615 |
520 def _MakeFieldDescriptor(self, field_proto, message_name, index, | 616 def _MakeFieldDescriptor(self, field_proto, message_name, index, |
521 is_extension=False): | 617 is_extension=False): |
522 """Creates a field descriptor from a FieldDescriptorProto. | 618 """Creates a field descriptor from a FieldDescriptorProto. |
523 | 619 |
524 For message and enum type fields, this method will do a look up | 620 For message and enum type fields, this method will do a look up |
525 in the pool for the appropriate descriptor for that type. If it | 621 in the pool for the appropriate descriptor for that type. If it |
(...skipping 24 matching lines...) Expand all Loading... |
550 type=field_proto.type, | 646 type=field_proto.type, |
551 cpp_type=None, | 647 cpp_type=None, |
552 message_type=None, | 648 message_type=None, |
553 enum_type=None, | 649 enum_type=None, |
554 containing_type=None, | 650 containing_type=None, |
555 label=field_proto.label, | 651 label=field_proto.label, |
556 has_default_value=False, | 652 has_default_value=False, |
557 default_value=None, | 653 default_value=None, |
558 is_extension=is_extension, | 654 is_extension=is_extension, |
559 extension_scope=None, | 655 extension_scope=None, |
560 options=field_proto.options) | 656 options=_OptionsOrNone(field_proto)) |
561 | 657 |
562 def _SetAllFieldTypes(self, package, desc_proto, scope): | 658 def _SetAllFieldTypes(self, package, desc_proto, scope): |
563 """Sets all the descriptor's fields's types. | 659 """Sets all the descriptor's fields's types. |
564 | 660 |
565 This method also sets the containing types on any extensions. | 661 This method also sets the containing types on any extensions. |
566 | 662 |
567 Args: | 663 Args: |
568 package: The current package of desc_proto. | 664 package: The current package of desc_proto. |
569 desc_proto: The message descriptor to update. | 665 desc_proto: The message descriptor to update. |
570 scope: Enclosing scope of available types. | 666 scope: Enclosing scope of available types. |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 index: The index of the enum value. | 765 index: The index of the enum value. |
670 | 766 |
671 Returns: | 767 Returns: |
672 An initialized EnumValueDescriptor object. | 768 An initialized EnumValueDescriptor object. |
673 """ | 769 """ |
674 | 770 |
675 return descriptor.EnumValueDescriptor( | 771 return descriptor.EnumValueDescriptor( |
676 name=value_proto.name, | 772 name=value_proto.name, |
677 index=index, | 773 index=index, |
678 number=value_proto.number, | 774 number=value_proto.number, |
679 options=value_proto.options, | 775 options=_OptionsOrNone(value_proto), |
680 type=None) | 776 type=None) |
681 | 777 |
| 778 def _MakeServiceDescriptor(self, service_proto, service_index, scope, |
| 779 package, file_desc): |
| 780 """Make a protobuf ServiceDescriptor given a ServiceDescriptorProto. |
| 781 |
| 782 Args: |
| 783 service_proto: The descriptor_pb2.ServiceDescriptorProto protobuf message. |
| 784 service_index: The index of the service in the File. |
| 785 scope: Dict mapping short and full symbols to message and enum types. |
| 786 package: Optional package name for the new message EnumDescriptor. |
| 787 file_desc: The file containing the service descriptor. |
| 788 |
| 789 Returns: |
| 790 The added descriptor. |
| 791 """ |
| 792 |
| 793 if package: |
| 794 service_name = '.'.join((package, service_proto.name)) |
| 795 else: |
| 796 service_name = service_proto.name |
| 797 |
| 798 methods = [self._MakeMethodDescriptor(method_proto, service_name, package, |
| 799 scope, index) |
| 800 for index, method_proto in enumerate(service_proto.method)] |
| 801 desc = descriptor.ServiceDescriptor(name=service_proto.name, |
| 802 full_name=service_name, |
| 803 index=service_index, |
| 804 methods=methods, |
| 805 options=_OptionsOrNone(service_proto), |
| 806 file=file_desc) |
| 807 return desc |
| 808 |
| 809 def _MakeMethodDescriptor(self, method_proto, service_name, package, scope, |
| 810 index): |
| 811 """Creates a method descriptor from a MethodDescriptorProto. |
| 812 |
| 813 Args: |
| 814 method_proto: The proto describing the method. |
| 815 service_name: The name of the containing service. |
| 816 package: Optional package name to look up for types. |
| 817 scope: Scope containing available types. |
| 818 index: Index of the method in the service. |
| 819 |
| 820 Returns: |
| 821 An initialized MethodDescriptor object. |
| 822 """ |
| 823 full_name = '.'.join((service_name, method_proto.name)) |
| 824 input_type = self._GetTypeFromScope( |
| 825 package, method_proto.input_type, scope) |
| 826 output_type = self._GetTypeFromScope( |
| 827 package, method_proto.output_type, scope) |
| 828 return descriptor.MethodDescriptor(name=method_proto.name, |
| 829 full_name=full_name, |
| 830 index=index, |
| 831 containing_service=None, |
| 832 input_type=input_type, |
| 833 output_type=output_type, |
| 834 options=_OptionsOrNone(method_proto)) |
| 835 |
682 def _ExtractSymbols(self, descriptors): | 836 def _ExtractSymbols(self, descriptors): |
683 """Pulls out all the symbols from descriptor protos. | 837 """Pulls out all the symbols from descriptor protos. |
684 | 838 |
685 Args: | 839 Args: |
686 descriptors: The messages to extract descriptors from. | 840 descriptors: The messages to extract descriptors from. |
687 Yields: | 841 Yields: |
688 A two element tuple of the type name and descriptor object. | 842 A two element tuple of the type name and descriptor object. |
689 """ | 843 """ |
690 | 844 |
691 for desc in descriptors: | 845 for desc in descriptors: |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 # TODO(amauryfa): This pool could be constructed from Python code, when we | 896 # TODO(amauryfa): This pool could be constructed from Python code, when we |
743 # support a flag like 'use_cpp_generated_pool=True'. | 897 # support a flag like 'use_cpp_generated_pool=True'. |
744 # pylint: disable=protected-access | 898 # pylint: disable=protected-access |
745 _DEFAULT = descriptor._message.default_pool | 899 _DEFAULT = descriptor._message.default_pool |
746 else: | 900 else: |
747 _DEFAULT = DescriptorPool() | 901 _DEFAULT = DescriptorPool() |
748 | 902 |
749 | 903 |
750 def Default(): | 904 def Default(): |
751 return _DEFAULT | 905 return _DEFAULT |
OLD | NEW |