| 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 | |
| 62 from google.protobuf import descriptor | 60 from google.protobuf import descriptor |
| 63 from google.protobuf import descriptor_database | 61 from google.protobuf import descriptor_database |
| 64 from google.protobuf import text_encoding | 62 from google.protobuf import text_encoding |
| 65 | 63 |
| 66 | 64 |
| 67 _USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS # pylint: disable=protected-
access | 65 _USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS |
| 68 | 66 |
| 69 | 67 |
| 70 def _NormalizeFullyQualifiedName(name): | 68 def _NormalizeFullyQualifiedName(name): |
| 71 """Remove leading period from fully-qualified type name. | 69 """Remove leading period from fully-qualified type name. |
| 72 | 70 |
| 73 Due to b/13860351 in descriptor_database.py, types in the root namespace are | 71 Due to b/13860351 in descriptor_database.py, types in the root namespace are |
| 74 generated with a leading period. This function removes that prefix. | 72 generated with a leading period. This function removes that prefix. |
| 75 | 73 |
| 76 Args: | 74 Args: |
| 77 name: A str, the fully-qualified symbol name. | 75 name: A str, the fully-qualified symbol name. |
| 78 | 76 |
| 79 Returns: | 77 Returns: |
| 80 A str, the normalized fully-qualified symbol name. | 78 A str, the normalized fully-qualified symbol name. |
| 81 """ | 79 """ |
| 82 return name.lstrip('.') | 80 return name.lstrip('.') |
| 83 | 81 |
| 84 | 82 |
| 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 | |
| 101 class DescriptorPool(object): | 83 class DescriptorPool(object): |
| 102 """A collection of protobufs dynamically constructed by descriptor protos.""" | 84 """A collection of protobufs dynamically constructed by descriptor protos.""" |
| 103 | 85 |
| 104 if _USE_C_DESCRIPTORS: | 86 if _USE_C_DESCRIPTORS: |
| 105 | 87 |
| 106 def __new__(cls, descriptor_db=None): | 88 def __new__(cls, descriptor_db=None): |
| 107 # pylint: disable=protected-access | 89 # pylint: disable=protected-access |
| 108 return descriptor._message.DescriptorPool(descriptor_db) | 90 return descriptor._message.DescriptorPool(descriptor_db) |
| 109 | 91 |
| 110 def __init__(self, descriptor_db=None): | 92 def __init__(self, descriptor_db=None): |
| 111 """Initializes a Pool of proto buffs. | 93 """Initializes a Pool of proto buffs. |
| 112 | 94 |
| 113 The descriptor_db argument to the constructor is provided to allow | 95 The descriptor_db argument to the constructor is provided to allow |
| 114 specialized file descriptor proto lookup code to be triggered on demand. An | 96 specialized file descriptor proto lookup code to be triggered on demand. An |
| 115 example would be an implementation which will read and compile a file | 97 example would be an implementation which will read and compile a file |
| 116 specified in a call to FindFileByName() and not require the call to Add() | 98 specified in a call to FindFileByName() and not require the call to Add() |
| 117 at all. Results from this database will be cached internally here as well. | 99 at all. Results from this database will be cached internally here as well. |
| 118 | 100 |
| 119 Args: | 101 Args: |
| 120 descriptor_db: A secondary source of file descriptors. | 102 descriptor_db: A secondary source of file descriptors. |
| 121 """ | 103 """ |
| 122 | 104 |
| 123 self._internal_db = descriptor_database.DescriptorDatabase() | 105 self._internal_db = descriptor_database.DescriptorDatabase() |
| 124 self._descriptor_db = descriptor_db | 106 self._descriptor_db = descriptor_db |
| 125 self._descriptors = {} | 107 self._descriptors = {} |
| 126 self._enum_descriptors = {} | 108 self._enum_descriptors = {} |
| 127 self._file_descriptors = {} | 109 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) | |
| 134 | 110 |
| 135 def Add(self, file_desc_proto): | 111 def Add(self, file_desc_proto): |
| 136 """Adds the FileDescriptorProto and its types to this pool. | 112 """Adds the FileDescriptorProto and its types to this pool. |
| 137 | 113 |
| 138 Args: | 114 Args: |
| 139 file_desc_proto: The FileDescriptorProto to add. | 115 file_desc_proto: The FileDescriptorProto to add. |
| 140 """ | 116 """ |
| 141 | 117 |
| 142 self._internal_db.Add(file_desc_proto) | 118 self._internal_db.Add(file_desc_proto) |
| 143 | 119 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 Args: | 155 Args: |
| 180 enum_desc: An EnumDescriptor. | 156 enum_desc: An EnumDescriptor. |
| 181 """ | 157 """ |
| 182 | 158 |
| 183 if not isinstance(enum_desc, descriptor.EnumDescriptor): | 159 if not isinstance(enum_desc, descriptor.EnumDescriptor): |
| 184 raise TypeError('Expected instance of descriptor.EnumDescriptor.') | 160 raise TypeError('Expected instance of descriptor.EnumDescriptor.') |
| 185 | 161 |
| 186 self._enum_descriptors[enum_desc.full_name] = enum_desc | 162 self._enum_descriptors[enum_desc.full_name] = enum_desc |
| 187 self.AddFileDescriptor(enum_desc.file) | 163 self.AddFileDescriptor(enum_desc.file) |
| 188 | 164 |
| 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 | |
| 231 def AddFileDescriptor(self, file_desc): | 165 def AddFileDescriptor(self, file_desc): |
| 232 """Adds a FileDescriptor to the pool, non-recursively. | 166 """Adds a FileDescriptor to the pool, non-recursively. |
| 233 | 167 |
| 234 If the FileDescriptor contains messages or enums, the caller must explicitly | 168 If the FileDescriptor contains messages or enums, the caller must explicitly |
| 235 register them. | 169 register them. |
| 236 | 170 |
| 237 Args: | 171 Args: |
| 238 file_desc: A FileDescriptor. | 172 file_desc: A FileDescriptor. |
| 239 """ | 173 """ |
| 240 | 174 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 def FindExtensionByName(self, full_name): | 287 def FindExtensionByName(self, full_name): |
| 354 """Loads the named extension descriptor from the pool. | 288 """Loads the named extension descriptor from the pool. |
| 355 | 289 |
| 356 Args: | 290 Args: |
| 357 full_name: The full name of the extension descriptor to load. | 291 full_name: The full name of the extension descriptor to load. |
| 358 | 292 |
| 359 Returns: | 293 Returns: |
| 360 A FieldDescriptor, describing the named extension. | 294 A FieldDescriptor, describing the named extension. |
| 361 """ | 295 """ |
| 362 full_name = _NormalizeFullyQualifiedName(full_name) | 296 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 | |
| 371 message_name, _, extension_name = full_name.rpartition('.') | 297 message_name, _, extension_name = full_name.rpartition('.') |
| 372 try: | 298 try: |
| 373 # Most extensions are nested inside a message. | 299 # Most extensions are nested inside a message. |
| 374 scope = self.FindMessageTypeByName(message_name) | 300 scope = self.FindMessageTypeByName(message_name) |
| 375 except KeyError: | 301 except KeyError: |
| 376 # Some extensions are defined at file scope. | 302 # Some extensions are defined at file scope. |
| 377 scope = self.FindFileContainingSymbol(full_name) | 303 scope = self.FindFileContainingSymbol(full_name) |
| 378 return scope.extensions_by_name[extension_name] | 304 return scope.extensions_by_name[extension_name] |
| 379 | 305 |
| 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 | |
| 413 def _ConvertFileProtoToFileDescriptor(self, file_proto): | 306 def _ConvertFileProtoToFileDescriptor(self, file_proto): |
| 414 """Creates a FileDescriptor from a proto or returns a cached copy. | 307 """Creates a FileDescriptor from a proto or returns a cached copy. |
| 415 | 308 |
| 416 This method also has the side effect of loading all the symbols found in | 309 This method also has the side effect of loading all the symbols found in |
| 417 the file into the appropriate dictionaries in the pool. | 310 the file into the appropriate dictionaries in the pool. |
| 418 | 311 |
| 419 Args: | 312 Args: |
| 420 file_proto: The proto to convert. | 313 file_proto: The proto to convert. |
| 421 | 314 |
| 422 Returns: | 315 Returns: |
| 423 A FileDescriptor matching the passed in proto. | 316 A FileDescriptor matching the passed in proto. |
| 424 """ | 317 """ |
| 425 | 318 |
| 426 if file_proto.name not in self._file_descriptors: | 319 if file_proto.name not in self._file_descriptors: |
| 427 built_deps = list(self._GetDeps(file_proto.dependency)) | 320 built_deps = list(self._GetDeps(file_proto.dependency)) |
| 428 direct_deps = [self.FindFileByName(n) for n in file_proto.dependency] | 321 direct_deps = [self.FindFileByName(n) for n in file_proto.dependency] |
| 429 public_deps = [direct_deps[i] for i in file_proto.public_dependency] | 322 public_deps = [direct_deps[i] for i in file_proto.public_dependency] |
| 430 | 323 |
| 431 file_descriptor = descriptor.FileDescriptor( | 324 file_descriptor = descriptor.FileDescriptor( |
| 432 pool=self, | 325 pool=self, |
| 433 name=file_proto.name, | 326 name=file_proto.name, |
| 434 package=file_proto.package, | 327 package=file_proto.package, |
| 435 syntax=file_proto.syntax, | 328 syntax=file_proto.syntax, |
| 436 options=_OptionsOrNone(file_proto), | 329 options=file_proto.options, |
| 437 serialized_pb=file_proto.SerializeToString(), | 330 serialized_pb=file_proto.SerializeToString(), |
| 438 dependencies=direct_deps, | 331 dependencies=direct_deps, |
| 439 public_dependencies=public_deps) | 332 public_dependencies=public_deps) |
| 440 scope = {} | 333 if _USE_C_DESCRIPTORS: |
| 334 # When using C++ descriptors, all objects defined in the file were added |
| 335 # to the C++ database when the FileDescriptor was built above. |
| 336 # Just add them to this descriptor pool. |
| 337 def _AddMessageDescriptor(message_desc): |
| 338 self._descriptors[message_desc.full_name] = message_desc |
| 339 for nested in message_desc.nested_types: |
| 340 _AddMessageDescriptor(nested) |
| 341 for enum_type in message_desc.enum_types: |
| 342 _AddEnumDescriptor(enum_type) |
| 343 def _AddEnumDescriptor(enum_desc): |
| 344 self._enum_descriptors[enum_desc.full_name] = enum_desc |
| 345 for message_type in file_descriptor.message_types_by_name.values(): |
| 346 _AddMessageDescriptor(message_type) |
| 347 for enum_type in file_descriptor.enum_types_by_name.values(): |
| 348 _AddEnumDescriptor(enum_type) |
| 349 else: |
| 350 scope = {} |
| 441 | 351 |
| 442 # This loop extracts all the message and enum types from all the | 352 # This loop extracts all the message and enum types from all the |
| 443 # dependencies of the file_proto. This is necessary to create the | 353 # dependencies of the file_proto. This is necessary to create the |
| 444 # scope of available message types when defining the passed in | 354 # scope of available message types when defining the passed in |
| 445 # file proto. | 355 # file proto. |
| 446 for dependency in built_deps: | 356 for dependency in built_deps: |
| 447 scope.update(self._ExtractSymbols( | 357 scope.update(self._ExtractSymbols( |
| 448 dependency.message_types_by_name.values())) | 358 dependency.message_types_by_name.values())) |
| 449 scope.update((_PrefixWithDot(enum.full_name), enum) | 359 scope.update((_PrefixWithDot(enum.full_name), enum) |
| 450 for enum in dependency.enum_types_by_name.values()) | 360 for enum in dependency.enum_types_by_name.values()) |
| 451 | 361 |
| 452 for message_type in file_proto.message_type: | 362 for message_type in file_proto.message_type: |
| 453 message_desc = self._ConvertMessageDescriptor( | 363 message_desc = self._ConvertMessageDescriptor( |
| 454 message_type, file_proto.package, file_descriptor, scope, | 364 message_type, file_proto.package, file_descriptor, scope, |
| 455 file_proto.syntax) | 365 file_proto.syntax) |
| 456 file_descriptor.message_types_by_name[message_desc.name] = ( | 366 file_descriptor.message_types_by_name[message_desc.name] = ( |
| 457 message_desc) | 367 message_desc) |
| 458 | 368 |
| 459 for enum_type in file_proto.enum_type: | 369 for enum_type in file_proto.enum_type: |
| 460 file_descriptor.enum_types_by_name[enum_type.name] = ( | 370 file_descriptor.enum_types_by_name[enum_type.name] = ( |
| 461 self._ConvertEnumDescriptor(enum_type, file_proto.package, | 371 self._ConvertEnumDescriptor(enum_type, file_proto.package, |
| 462 file_descriptor, None, scope)) | 372 file_descriptor, None, scope)) |
| 463 | 373 |
| 464 for index, extension_proto in enumerate(file_proto.extension): | 374 for index, extension_proto in enumerate(file_proto.extension): |
| 465 extension_desc = self._MakeFieldDescriptor( | 375 extension_desc = self._MakeFieldDescriptor( |
| 466 extension_proto, file_proto.package, index, is_extension=True) | 376 extension_proto, file_proto.package, index, is_extension=True) |
| 467 extension_desc.containing_type = self._GetTypeFromScope( | 377 extension_desc.containing_type = self._GetTypeFromScope( |
| 468 file_descriptor.package, extension_proto.extendee, scope) | 378 file_descriptor.package, extension_proto.extendee, scope) |
| 469 self._SetFieldType(extension_proto, extension_desc, | 379 self._SetFieldType(extension_proto, extension_desc, |
| 470 file_descriptor.package, scope) | 380 file_descriptor.package, scope) |
| 471 file_descriptor.extensions_by_name[extension_desc.name] = ( | 381 file_descriptor.extensions_by_name[extension_desc.name] = ( |
| 472 extension_desc) | 382 extension_desc) |
| 473 | 383 |
| 474 for desc_proto in file_proto.message_type: | 384 for desc_proto in file_proto.message_type: |
| 475 self._SetAllFieldTypes(file_proto.package, desc_proto, scope) | 385 self._SetAllFieldTypes(file_proto.package, desc_proto, scope) |
| 476 | 386 |
| 477 if file_proto.package: | 387 if file_proto.package: |
| 478 desc_proto_prefix = _PrefixWithDot(file_proto.package) | 388 desc_proto_prefix = _PrefixWithDot(file_proto.package) |
| 479 else: | 389 else: |
| 480 desc_proto_prefix = '' | 390 desc_proto_prefix = '' |
| 481 | 391 |
| 482 for desc_proto in file_proto.message_type: | 392 for desc_proto in file_proto.message_type: |
| 483 desc = self._GetTypeFromScope( | 393 desc = self._GetTypeFromScope( |
| 484 desc_proto_prefix, desc_proto.name, scope) | 394 desc_proto_prefix, desc_proto.name, scope) |
| 485 file_descriptor.message_types_by_name[desc_proto.name] = desc | 395 file_descriptor.message_types_by_name[desc_proto.name] = desc |
| 486 | |
| 487 for index, service_proto in enumerate(file_proto.service): | |
| 488 file_descriptor.services_by_name[service_proto.name] = ( | |
| 489 self._MakeServiceDescriptor(service_proto, index, scope, | |
| 490 file_proto.package, file_descriptor)) | |
| 491 | 396 |
| 492 self.Add(file_proto) | 397 self.Add(file_proto) |
| 493 self._file_descriptors[file_proto.name] = file_descriptor | 398 self._file_descriptors[file_proto.name] = file_descriptor |
| 494 | 399 |
| 495 return self._file_descriptors[file_proto.name] | 400 return self._file_descriptors[file_proto.name] |
| 496 | 401 |
| 497 def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None, | 402 def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None, |
| 498 scope=None, syntax=None): | 403 scope=None, syntax=None): |
| 499 """Adds the proto to the pool in the specified package. | 404 """Adds the proto to the pool in the specified package. |
| 500 | 405 |
| 501 Args: | 406 Args: |
| 502 desc_proto: The descriptor_pb2.DescriptorProto protobuf message. | 407 desc_proto: The descriptor_pb2.DescriptorProto protobuf message. |
| 503 package: The package the proto should be located in. | 408 package: The package the proto should be located in. |
| 504 file_desc: The file containing this message. | 409 file_desc: The file containing this message. |
| 505 scope: Dict mapping short and full symbols to message and enum types. | 410 scope: Dict mapping short and full symbols to message and enum types. |
| 506 syntax: string indicating syntax of the file ("proto2" or "proto3") | |
| 507 | 411 |
| 508 Returns: | 412 Returns: |
| 509 The added descriptor. | 413 The added descriptor. |
| 510 """ | 414 """ |
| 511 | 415 |
| 512 if package: | 416 if package: |
| 513 desc_name = '.'.join((package, desc_proto.name)) | 417 desc_name = '.'.join((package, desc_proto.name)) |
| 514 else: | 418 else: |
| 515 desc_name = desc_proto.name | 419 desc_name = desc_proto.name |
| 516 | 420 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 530 self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope) | 434 self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope) |
| 531 for enum in desc_proto.enum_type] | 435 for enum in desc_proto.enum_type] |
| 532 fields = [self._MakeFieldDescriptor(field, desc_name, index) | 436 fields = [self._MakeFieldDescriptor(field, desc_name, index) |
| 533 for index, field in enumerate(desc_proto.field)] | 437 for index, field in enumerate(desc_proto.field)] |
| 534 extensions = [ | 438 extensions = [ |
| 535 self._MakeFieldDescriptor(extension, desc_name, index, | 439 self._MakeFieldDescriptor(extension, desc_name, index, |
| 536 is_extension=True) | 440 is_extension=True) |
| 537 for index, extension in enumerate(desc_proto.extension)] | 441 for index, extension in enumerate(desc_proto.extension)] |
| 538 oneofs = [ | 442 oneofs = [ |
| 539 descriptor.OneofDescriptor(desc.name, '.'.join((desc_name, desc.name)), | 443 descriptor.OneofDescriptor(desc.name, '.'.join((desc_name, desc.name)), |
| 540 index, None, [], desc.options) | 444 index, None, []) |
| 541 for index, desc in enumerate(desc_proto.oneof_decl)] | 445 for index, desc in enumerate(desc_proto.oneof_decl)] |
| 542 extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range] | 446 extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range] |
| 543 if extension_ranges: | 447 if extension_ranges: |
| 544 is_extendable = True | 448 is_extendable = True |
| 545 else: | 449 else: |
| 546 is_extendable = False | 450 is_extendable = False |
| 547 desc = descriptor.Descriptor( | 451 desc = descriptor.Descriptor( |
| 548 name=desc_proto.name, | 452 name=desc_proto.name, |
| 549 full_name=desc_name, | 453 full_name=desc_name, |
| 550 filename=file_name, | 454 filename=file_name, |
| 551 containing_type=None, | 455 containing_type=None, |
| 552 fields=fields, | 456 fields=fields, |
| 553 oneofs=oneofs, | 457 oneofs=oneofs, |
| 554 nested_types=nested, | 458 nested_types=nested, |
| 555 enum_types=enums, | 459 enum_types=enums, |
| 556 extensions=extensions, | 460 extensions=extensions, |
| 557 options=_OptionsOrNone(desc_proto), | 461 options=desc_proto.options, |
| 558 is_extendable=is_extendable, | 462 is_extendable=is_extendable, |
| 559 extension_ranges=extension_ranges, | 463 extension_ranges=extension_ranges, |
| 560 file=file_desc, | 464 file=file_desc, |
| 561 serialized_start=None, | 465 serialized_start=None, |
| 562 serialized_end=None, | 466 serialized_end=None, |
| 563 syntax=syntax) | 467 syntax=syntax) |
| 564 for nested in desc.nested_types: | 468 for nested in desc.nested_types: |
| 565 nested.containing_type = desc | 469 nested.containing_type = desc |
| 566 for enum in desc.enum_types: | 470 for enum in desc.enum_types: |
| 567 enum.containing_type = desc | 471 enum.containing_type = desc |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 file_name = file_desc.name | 505 file_name = file_desc.name |
| 602 | 506 |
| 603 values = [self._MakeEnumValueDescriptor(value, index) | 507 values = [self._MakeEnumValueDescriptor(value, index) |
| 604 for index, value in enumerate(enum_proto.value)] | 508 for index, value in enumerate(enum_proto.value)] |
| 605 desc = descriptor.EnumDescriptor(name=enum_proto.name, | 509 desc = descriptor.EnumDescriptor(name=enum_proto.name, |
| 606 full_name=enum_name, | 510 full_name=enum_name, |
| 607 filename=file_name, | 511 filename=file_name, |
| 608 file=file_desc, | 512 file=file_desc, |
| 609 values=values, | 513 values=values, |
| 610 containing_type=containing_type, | 514 containing_type=containing_type, |
| 611 options=_OptionsOrNone(enum_proto)) | 515 options=enum_proto.options) |
| 612 scope['.%s' % enum_name] = desc | 516 scope['.%s' % enum_name] = desc |
| 613 self._enum_descriptors[enum_name] = desc | 517 self._enum_descriptors[enum_name] = desc |
| 614 return desc | 518 return desc |
| 615 | 519 |
| 616 def _MakeFieldDescriptor(self, field_proto, message_name, index, | 520 def _MakeFieldDescriptor(self, field_proto, message_name, index, |
| 617 is_extension=False): | 521 is_extension=False): |
| 618 """Creates a field descriptor from a FieldDescriptorProto. | 522 """Creates a field descriptor from a FieldDescriptorProto. |
| 619 | 523 |
| 620 For message and enum type fields, this method will do a look up | 524 For message and enum type fields, this method will do a look up |
| 621 in the pool for the appropriate descriptor for that type. If it | 525 in the pool for the appropriate descriptor for that type. If it |
| (...skipping 24 matching lines...) Expand all Loading... |
| 646 type=field_proto.type, | 550 type=field_proto.type, |
| 647 cpp_type=None, | 551 cpp_type=None, |
| 648 message_type=None, | 552 message_type=None, |
| 649 enum_type=None, | 553 enum_type=None, |
| 650 containing_type=None, | 554 containing_type=None, |
| 651 label=field_proto.label, | 555 label=field_proto.label, |
| 652 has_default_value=False, | 556 has_default_value=False, |
| 653 default_value=None, | 557 default_value=None, |
| 654 is_extension=is_extension, | 558 is_extension=is_extension, |
| 655 extension_scope=None, | 559 extension_scope=None, |
| 656 options=_OptionsOrNone(field_proto)) | 560 options=field_proto.options) |
| 657 | 561 |
| 658 def _SetAllFieldTypes(self, package, desc_proto, scope): | 562 def _SetAllFieldTypes(self, package, desc_proto, scope): |
| 659 """Sets all the descriptor's fields's types. | 563 """Sets all the descriptor's fields's types. |
| 660 | 564 |
| 661 This method also sets the containing types on any extensions. | 565 This method also sets the containing types on any extensions. |
| 662 | 566 |
| 663 Args: | 567 Args: |
| 664 package: The current package of desc_proto. | 568 package: The current package of desc_proto. |
| 665 desc_proto: The message descriptor to update. | 569 desc_proto: The message descriptor to update. |
| 666 scope: Enclosing scope of available types. | 570 scope: Enclosing scope of available types. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 index: The index of the enum value. | 669 index: The index of the enum value. |
| 766 | 670 |
| 767 Returns: | 671 Returns: |
| 768 An initialized EnumValueDescriptor object. | 672 An initialized EnumValueDescriptor object. |
| 769 """ | 673 """ |
| 770 | 674 |
| 771 return descriptor.EnumValueDescriptor( | 675 return descriptor.EnumValueDescriptor( |
| 772 name=value_proto.name, | 676 name=value_proto.name, |
| 773 index=index, | 677 index=index, |
| 774 number=value_proto.number, | 678 number=value_proto.number, |
| 775 options=_OptionsOrNone(value_proto), | 679 options=value_proto.options, |
| 776 type=None) | 680 type=None) |
| 777 | 681 |
| 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 | |
| 836 def _ExtractSymbols(self, descriptors): | 682 def _ExtractSymbols(self, descriptors): |
| 837 """Pulls out all the symbols from descriptor protos. | 683 """Pulls out all the symbols from descriptor protos. |
| 838 | 684 |
| 839 Args: | 685 Args: |
| 840 descriptors: The messages to extract descriptors from. | 686 descriptors: The messages to extract descriptors from. |
| 841 Yields: | 687 Yields: |
| 842 A two element tuple of the type name and descriptor object. | 688 A two element tuple of the type name and descriptor object. |
| 843 """ | 689 """ |
| 844 | 690 |
| 845 for desc in descriptors: | 691 for desc in descriptors: |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 896 # TODO(amauryfa): This pool could be constructed from Python code, when we | 742 # TODO(amauryfa): This pool could be constructed from Python code, when we |
| 897 # support a flag like 'use_cpp_generated_pool=True'. | 743 # support a flag like 'use_cpp_generated_pool=True'. |
| 898 # pylint: disable=protected-access | 744 # pylint: disable=protected-access |
| 899 _DEFAULT = descriptor._message.default_pool | 745 _DEFAULT = descriptor._message.default_pool |
| 900 else: | 746 else: |
| 901 _DEFAULT = DescriptorPool() | 747 _DEFAULT = DescriptorPool() |
| 902 | 748 |
| 903 | 749 |
| 904 def Default(): | 750 def Default(): |
| 905 return _DEFAULT | 751 return _DEFAULT |
| OLD | NEW |