| 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 |