Package google :: Package protobuf :: Module descriptor
[frames] | no frames]

Source Code for Module google.protobuf.descriptor

  1  # Protocol Buffers - Google's data interchange format 
  2  # Copyright 2008 Google Inc.  All rights reserved. 
  3  # https://developers.google.com/protocol-buffers/ 
  4  # 
  5  # Redistribution and use in source and binary forms, with or without 
  6  # modification, are permitted provided that the following conditions are 
  7  # met: 
  8  # 
  9  #     * Redistributions of source code must retain the above copyright 
 10  # notice, this list of conditions and the following disclaimer. 
 11  #     * Redistributions in binary form must reproduce the above 
 12  # copyright notice, this list of conditions and the following disclaimer 
 13  # in the documentation and/or other materials provided with the 
 14  # distribution. 
 15  #     * Neither the name of Google Inc. nor the names of its 
 16  # contributors may be used to endorse or promote products derived from 
 17  # this software without specific prior written permission. 
 18  # 
 19  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 20  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 21  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 22  # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 23  # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 24  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 25  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 26  # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
 27  # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 28  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 29  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 30   
 31  """Descriptors essentially contain exactly the information found in a .proto 
 32  file, in types that make this information accessible in Python. 
 33  """ 
 34   
 35  __author__ = 'robinson@google.com (Will Robinson)' 
 36   
 37  import six 
 38   
 39  from google.protobuf.internal import api_implementation 
 40   
 41  _USE_C_DESCRIPTORS = False 
 42  if api_implementation.Type() == 'cpp': 
 43    # Used by MakeDescriptor in cpp mode 
 44    import os 
 45    import uuid 
 46    from google.protobuf.pyext import _message 
 47    _USE_C_DESCRIPTORS = getattr(_message, '_USE_C_DESCRIPTORS', False) 
48 49 50 -class Error(Exception):
51 """Base error for this module."""
52
53 54 -class TypeTransformationError(Error):
55 """Error transforming between python proto type and corresponding C++ type."""
56 57 58 if _USE_C_DESCRIPTORS:
59 # This metaclass allows to override the behavior of code like 60 # isinstance(my_descriptor, FieldDescriptor) 61 # and make it return True when the descriptor is an instance of the extension 62 # type written in C++. 63 - class DescriptorMetaclass(type):
64 - def __instancecheck__(cls, obj):
65 if super(DescriptorMetaclass, cls).__instancecheck__(obj): 66 return True 67 if isinstance(obj, cls._C_DESCRIPTOR_CLASS): 68 return True 69 return False
70 else: 71 # The standard metaclass; nothing changes. 72 DescriptorMetaclass = type
73 74 75 -class DescriptorBase(six.with_metaclass(DescriptorMetaclass)):
76 77 """Descriptors base class. 78 79 This class is the base of all descriptor classes. It provides common options 80 related functionality. 81 82 Attributes: 83 has_options: True if the descriptor has non-default options. Usually it 84 is not necessary to read this -- just call GetOptions() which will 85 happily return the default instance. However, it's sometimes useful 86 for efficiency, and also useful inside the protobuf implementation to 87 avoid some bootstrapping issues. 88 """ 89 90 if _USE_C_DESCRIPTORS: 91 # The class, or tuple of classes, that are considered as "virtual 92 # subclasses" of this descriptor class. 93 _C_DESCRIPTOR_CLASS = () 94
95 - def __init__(self, options, options_class_name):
96 """Initialize the descriptor given its options message and the name of the 97 class of the options message. The name of the class is required in case 98 the options message is None and has to be created. 99 """ 100 self._options = options 101 self._options_class_name = options_class_name 102 103 # Does this descriptor have non-default options? 104 self.has_options = options is not None
105
106 - def _SetOptions(self, options, options_class_name):
107 """Sets the descriptor's options 108 109 This function is used in generated proto2 files to update descriptor 110 options. It must not be used outside proto2. 111 """ 112 self._options = options 113 self._options_class_name = options_class_name 114 115 # Does this descriptor have non-default options? 116 self.has_options = options is not None
117
118 - def GetOptions(self):
119 """Retrieves descriptor options. 120 121 This method returns the options set or creates the default options for the 122 descriptor. 123 """ 124 if self._options: 125 return self._options 126 from google.protobuf import descriptor_pb2 127 try: 128 options_class = getattr(descriptor_pb2, self._options_class_name) 129 except AttributeError: 130 raise RuntimeError('Unknown options class name %s!' % 131 (self._options_class_name)) 132 self._options = options_class() 133 return self._options
134
135 136 -class _NestedDescriptorBase(DescriptorBase):
137 """Common class for descriptors that can be nested.""" 138
139 - def __init__(self, options, options_class_name, name, full_name, 140 file, containing_type, serialized_start=None, 141 serialized_end=None):
142 """Constructor. 143 144 Args: 145 options: Protocol message options or None 146 to use default message options. 147 options_class_name: (str) The class name of the above options. 148 149 name: (str) Name of this protocol message type. 150 full_name: (str) Fully-qualified name of this protocol message type, 151 which will include protocol "package" name and the name of any 152 enclosing types. 153 file: (FileDescriptor) Reference to file info. 154 containing_type: if provided, this is a nested descriptor, with this 155 descriptor as parent, otherwise None. 156 serialized_start: The start index (inclusive) in block in the 157 file.serialized_pb that describes this descriptor. 158 serialized_end: The end index (exclusive) in block in the 159 file.serialized_pb that describes this descriptor. 160 """ 161 super(_NestedDescriptorBase, self).__init__( 162 options, options_class_name) 163 164 self.name = name 165 # TODO(falk): Add function to calculate full_name instead of having it in 166 # memory? 167 self.full_name = full_name 168 self.file = file 169 self.containing_type = containing_type 170 171 self._serialized_start = serialized_start 172 self._serialized_end = serialized_end
173
175 """Returns the root if this is a nested type, or itself if its the root.""" 176 desc = self 177 while desc.containing_type is not None: 178 desc = desc.containing_type 179 return desc
180
181 - def CopyToProto(self, proto):
182 """Copies this to the matching proto in descriptor_pb2. 183 184 Args: 185 proto: An empty proto instance from descriptor_pb2. 186 187 Raises: 188 Error: If self couldnt be serialized, due to to few constructor arguments. 189 """ 190 if (self.file is not None and 191 self._serialized_start is not None and 192 self._serialized_end is not None): 193 proto.ParseFromString(self.file.serialized_pb[ 194 self._serialized_start:self._serialized_end]) 195 else: 196 raise Error('Descriptor does not contain serialization.')
197
198 199 -class Descriptor(_NestedDescriptorBase):
200 201 """Descriptor for a protocol message type. 202 203 A Descriptor instance has the following attributes: 204 205 name: (str) Name of this protocol message type. 206 full_name: (str) Fully-qualified name of this protocol message type, 207 which will include protocol "package" name and the name of any 208 enclosing types. 209 210 containing_type: (Descriptor) Reference to the descriptor of the 211 type containing us, or None if this is top-level. 212 213 fields: (list of FieldDescriptors) Field descriptors for all 214 fields in this type. 215 fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor 216 objects as in |fields|, but indexed by "number" attribute in each 217 FieldDescriptor. 218 fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor 219 objects as in |fields|, but indexed by "name" attribute in each 220 FieldDescriptor. 221 fields_by_camelcase_name: (dict str -> FieldDescriptor) Same 222 FieldDescriptor objects as in |fields|, but indexed by 223 "camelcase_name" attribute in each FieldDescriptor. 224 225 nested_types: (list of Descriptors) Descriptor references 226 for all protocol message types nested within this one. 227 nested_types_by_name: (dict str -> Descriptor) Same Descriptor 228 objects as in |nested_types|, but indexed by "name" attribute 229 in each Descriptor. 230 231 enum_types: (list of EnumDescriptors) EnumDescriptor references 232 for all enums contained within this type. 233 enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor 234 objects as in |enum_types|, but indexed by "name" attribute 235 in each EnumDescriptor. 236 enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping 237 from enum value name to EnumValueDescriptor for that value. 238 239 extensions: (list of FieldDescriptor) All extensions defined directly 240 within this message type (NOT within a nested type). 241 extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor 242 objects as |extensions|, but indexed by "name" attribute of each 243 FieldDescriptor. 244 245 is_extendable: Does this type define any extension ranges? 246 247 oneofs: (list of OneofDescriptor) The list of descriptors for oneof fields 248 in this message. 249 oneofs_by_name: (dict str -> OneofDescriptor) Same objects as in |oneofs|, 250 but indexed by "name" attribute. 251 252 file: (FileDescriptor) Reference to file descriptor. 253 """ 254 255 if _USE_C_DESCRIPTORS: 256 _C_DESCRIPTOR_CLASS = _message.Descriptor 257
258 - def __new__(cls, name, full_name, filename, containing_type, fields, 259 nested_types, enum_types, extensions, options=None, 260 is_extendable=True, extension_ranges=None, oneofs=None, 261 file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin 262 syntax=None):
263 _message.Message._CheckCalledFromGeneratedFile() 264 return _message.default_pool.FindMessageTypeByName(full_name)
265 266 # NOTE(tmarek): The file argument redefining a builtin is nothing we can 267 # fix right now since we don't know how many clients already rely on the 268 # name of the argument.
269 - def __init__(self, name, full_name, filename, containing_type, fields, 270 nested_types, enum_types, extensions, options=None, 271 is_extendable=True, extension_ranges=None, oneofs=None, 272 file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin 273 syntax=None):
274 """Arguments to __init__() are as described in the description 275 of Descriptor fields above. 276 277 Note that filename is an obsolete argument, that is not used anymore. 278 Please use file.name to access this as an attribute. 279 """ 280 super(Descriptor, self).__init__( 281 options, 'MessageOptions', name, full_name, file, 282 containing_type, serialized_start=serialized_start, 283 serialized_end=serialized_end) 284 285 # We have fields in addition to fields_by_name and fields_by_number, 286 # so that: 287 # 1. Clients can index fields by "order in which they're listed." 288 # 2. Clients can easily iterate over all fields with the terse 289 # syntax: for f in descriptor.fields: ... 290 self.fields = fields 291 for field in self.fields: 292 field.containing_type = self 293 self.fields_by_number = dict((f.number, f) for f in fields) 294 self.fields_by_name = dict((f.name, f) for f in fields) 295 self._fields_by_camelcase_name = None 296 297 self.nested_types = nested_types 298 for nested_type in nested_types: 299 nested_type.containing_type = self 300 self.nested_types_by_name = dict((t.name, t) for t in nested_types) 301 302 self.enum_types = enum_types 303 for enum_type in self.enum_types: 304 enum_type.containing_type = self 305 self.enum_types_by_name = dict((t.name, t) for t in enum_types) 306 self.enum_values_by_name = dict( 307 (v.name, v) for t in enum_types for v in t.values) 308 309 self.extensions = extensions 310 for extension in self.extensions: 311 extension.extension_scope = self 312 self.extensions_by_name = dict((f.name, f) for f in extensions) 313 self.is_extendable = is_extendable 314 self.extension_ranges = extension_ranges 315 self.oneofs = oneofs if oneofs is not None else [] 316 self.oneofs_by_name = dict((o.name, o) for o in self.oneofs) 317 for oneof in self.oneofs: 318 oneof.containing_type = self 319 self.syntax = syntax or "proto2"
320 321 @property
322 - def fields_by_camelcase_name(self):
323 if self._fields_by_camelcase_name is None: 324 self._fields_by_camelcase_name = dict( 325 (f.camelcase_name, f) for f in self.fields) 326 return self._fields_by_camelcase_name
327
328 - def EnumValueName(self, enum, value):
329 """Returns the string name of an enum value. 330 331 This is just a small helper method to simplify a common operation. 332 333 Args: 334 enum: string name of the Enum. 335 value: int, value of the enum. 336 337 Returns: 338 string name of the enum value. 339 340 Raises: 341 KeyError if either the Enum doesn't exist or the value is not a valid 342 value for the enum. 343 """ 344 return self.enum_types_by_name[enum].values_by_number[value].name
345
346 - def CopyToProto(self, proto):
347 """Copies this to a descriptor_pb2.DescriptorProto. 348 349 Args: 350 proto: An empty descriptor_pb2.DescriptorProto. 351 """ 352 # This function is overridden to give a better doc comment. 353 super(Descriptor, self).CopyToProto(proto)
354
355 356 # TODO(robinson): We should have aggressive checking here, 357 # for example: 358 # * If you specify a repeated field, you should not be allowed 359 # to specify a default value. 360 # * [Other examples here as needed]. 361 # 362 # TODO(robinson): for this and other *Descriptor classes, we 363 # might also want to lock things down aggressively (e.g., 364 # prevent clients from setting the attributes). Having 365 # stronger invariants here in general will reduce the number 366 # of runtime checks we must do in reflection.py... 367 -class FieldDescriptor(DescriptorBase):
368 369 """Descriptor for a single field in a .proto file. 370 371 A FieldDescriptor instance has the following attributes: 372 373 name: (str) Name of this field, exactly as it appears in .proto. 374 full_name: (str) Name of this field, including containing scope. This is 375 particularly relevant for extensions. 376 camelcase_name: (str) Camelcase name of this field. 377 index: (int) Dense, 0-indexed index giving the order that this 378 field textually appears within its message in the .proto file. 379 number: (int) Tag number declared for this field in the .proto file. 380 381 type: (One of the TYPE_* constants below) Declared type. 382 cpp_type: (One of the CPPTYPE_* constants below) C++ type used to 383 represent this field. 384 385 label: (One of the LABEL_* constants below) Tells whether this 386 field is optional, required, or repeated. 387 has_default_value: (bool) True if this field has a default value defined, 388 otherwise false. 389 default_value: (Varies) Default value of this field. Only 390 meaningful for non-repeated scalar fields. Repeated fields 391 should always set this to [], and non-repeated composite 392 fields should always set this to None. 393 394 containing_type: (Descriptor) Descriptor of the protocol message 395 type that contains this field. Set by the Descriptor constructor 396 if we're passed into one. 397 Somewhat confusingly, for extension fields, this is the 398 descriptor of the EXTENDED message, not the descriptor 399 of the message containing this field. (See is_extension and 400 extension_scope below). 401 message_type: (Descriptor) If a composite field, a descriptor 402 of the message type contained in this field. Otherwise, this is None. 403 enum_type: (EnumDescriptor) If this field contains an enum, a 404 descriptor of that enum. Otherwise, this is None. 405 406 is_extension: True iff this describes an extension field. 407 extension_scope: (Descriptor) Only meaningful if is_extension is True. 408 Gives the message that immediately contains this extension field. 409 Will be None iff we're a top-level (file-level) extension field. 410 411 options: (descriptor_pb2.FieldOptions) Protocol message field options or 412 None to use default field options. 413 414 containing_oneof: (OneofDescriptor) If the field is a member of a oneof 415 union, contains its descriptor. Otherwise, None. 416 """ 417 418 # Must be consistent with C++ FieldDescriptor::Type enum in 419 # descriptor.h. 420 # 421 # TODO(robinson): Find a way to eliminate this repetition. 422 TYPE_DOUBLE = 1 423 TYPE_FLOAT = 2 424 TYPE_INT64 = 3 425 TYPE_UINT64 = 4 426 TYPE_INT32 = 5 427 TYPE_FIXED64 = 6 428 TYPE_FIXED32 = 7 429 TYPE_BOOL = 8 430 TYPE_STRING = 9 431 TYPE_GROUP = 10 432 TYPE_MESSAGE = 11 433 TYPE_BYTES = 12 434 TYPE_UINT32 = 13 435 TYPE_ENUM = 14 436 TYPE_SFIXED32 = 15 437 TYPE_SFIXED64 = 16 438 TYPE_SINT32 = 17 439 TYPE_SINT64 = 18 440 MAX_TYPE = 18 441 442 # Must be consistent with C++ FieldDescriptor::CppType enum in 443 # descriptor.h. 444 # 445 # TODO(robinson): Find a way to eliminate this repetition. 446 CPPTYPE_INT32 = 1 447 CPPTYPE_INT64 = 2 448 CPPTYPE_UINT32 = 3 449 CPPTYPE_UINT64 = 4 450 CPPTYPE_DOUBLE = 5 451 CPPTYPE_FLOAT = 6 452 CPPTYPE_BOOL = 7 453 CPPTYPE_ENUM = 8 454 CPPTYPE_STRING = 9 455 CPPTYPE_MESSAGE = 10 456 MAX_CPPTYPE = 10 457 458 _PYTHON_TO_CPP_PROTO_TYPE_MAP = { 459 TYPE_DOUBLE: CPPTYPE_DOUBLE, 460 TYPE_FLOAT: CPPTYPE_FLOAT, 461 TYPE_ENUM: CPPTYPE_ENUM, 462 TYPE_INT64: CPPTYPE_INT64, 463 TYPE_SINT64: CPPTYPE_INT64, 464 TYPE_SFIXED64: CPPTYPE_INT64, 465 TYPE_UINT64: CPPTYPE_UINT64, 466 TYPE_FIXED64: CPPTYPE_UINT64, 467 TYPE_INT32: CPPTYPE_INT32, 468 TYPE_SFIXED32: CPPTYPE_INT32, 469 TYPE_SINT32: CPPTYPE_INT32, 470 TYPE_UINT32: CPPTYPE_UINT32, 471 TYPE_FIXED32: CPPTYPE_UINT32, 472 TYPE_BYTES: CPPTYPE_STRING, 473 TYPE_STRING: CPPTYPE_STRING, 474 TYPE_BOOL: CPPTYPE_BOOL, 475 TYPE_MESSAGE: CPPTYPE_MESSAGE, 476 TYPE_GROUP: CPPTYPE_MESSAGE 477 } 478 479 # Must be consistent with C++ FieldDescriptor::Label enum in 480 # descriptor.h. 481 # 482 # TODO(robinson): Find a way to eliminate this repetition. 483 LABEL_OPTIONAL = 1 484 LABEL_REQUIRED = 2 485 LABEL_REPEATED = 3 486 MAX_LABEL = 3 487 488 # Must be consistent with C++ constants kMaxNumber, kFirstReservedNumber, 489 # and kLastReservedNumber in descriptor.h 490 MAX_FIELD_NUMBER = (1 << 29) - 1 491 FIRST_RESERVED_FIELD_NUMBER = 19000 492 LAST_RESERVED_FIELD_NUMBER = 19999 493 494 if _USE_C_DESCRIPTORS: 495 _C_DESCRIPTOR_CLASS = _message.FieldDescriptor 496
497 - def __new__(cls, name, full_name, index, number, type, cpp_type, label, 498 default_value, message_type, enum_type, containing_type, 499 is_extension, extension_scope, options=None, 500 has_default_value=True, containing_oneof=None):
501 _message.Message._CheckCalledFromGeneratedFile() 502 if is_extension: 503 return _message.default_pool.FindExtensionByName(full_name) 504 else: 505 return _message.default_pool.FindFieldByName(full_name)
506
507 - def __init__(self, name, full_name, index, number, type, cpp_type, label, 508 default_value, message_type, enum_type, containing_type, 509 is_extension, extension_scope, options=None, 510 has_default_value=True, containing_oneof=None):
511 """The arguments are as described in the description of FieldDescriptor 512 attributes above. 513 514 Note that containing_type may be None, and may be set later if necessary 515 (to deal with circular references between message types, for example). 516 Likewise for extension_scope. 517 """ 518 super(FieldDescriptor, self).__init__(options, 'FieldOptions') 519 self.name = name 520 self.full_name = full_name 521 self._camelcase_name = None 522 self.index = index 523 self.number = number 524 self.type = type 525 self.cpp_type = cpp_type 526 self.label = label 527 self.has_default_value = has_default_value 528 self.default_value = default_value 529 self.containing_type = containing_type 530 self.message_type = message_type 531 self.enum_type = enum_type 532 self.is_extension = is_extension 533 self.extension_scope = extension_scope 534 self.containing_oneof = containing_oneof 535 if api_implementation.Type() == 'cpp': 536 if is_extension: 537 self._cdescriptor = _message.default_pool.FindExtensionByName(full_name) 538 else: 539 self._cdescriptor = _message.default_pool.FindFieldByName(full_name) 540 else: 541 self._cdescriptor = None
542 543 @property
544 - def camelcase_name(self):
545 if self._camelcase_name is None: 546 self._camelcase_name = _ToCamelCase(self.name) 547 return self._camelcase_name
548 549 @staticmethod
550 - def ProtoTypeToCppProtoType(proto_type):
551 """Converts from a Python proto type to a C++ Proto Type. 552 553 The Python ProtocolBuffer classes specify both the 'Python' datatype and the 554 'C++' datatype - and they're not the same. This helper method should 555 translate from one to another. 556 557 Args: 558 proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*) 559 Returns: 560 descriptor.FieldDescriptor.CPPTYPE_*, the C++ type. 561 Raises: 562 TypeTransformationError: when the Python proto type isn't known. 563 """ 564 try: 565 return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type] 566 except KeyError: 567 raise TypeTransformationError('Unknown proto_type: %s' % proto_type)
568
569 570 -class EnumDescriptor(_NestedDescriptorBase):
571 572 """Descriptor for an enum defined in a .proto file. 573 574 An EnumDescriptor instance has the following attributes: 575 576 name: (str) Name of the enum type. 577 full_name: (str) Full name of the type, including package name 578 and any enclosing type(s). 579 580 values: (list of EnumValueDescriptors) List of the values 581 in this enum. 582 values_by_name: (dict str -> EnumValueDescriptor) Same as |values|, 583 but indexed by the "name" field of each EnumValueDescriptor. 584 values_by_number: (dict int -> EnumValueDescriptor) Same as |values|, 585 but indexed by the "number" field of each EnumValueDescriptor. 586 containing_type: (Descriptor) Descriptor of the immediate containing 587 type of this enum, or None if this is an enum defined at the 588 top level in a .proto file. Set by Descriptor's constructor 589 if we're passed into one. 590 file: (FileDescriptor) Reference to file descriptor. 591 options: (descriptor_pb2.EnumOptions) Enum options message or 592 None to use default enum options. 593 """ 594 595 if _USE_C_DESCRIPTORS: 596 _C_DESCRIPTOR_CLASS = _message.EnumDescriptor 597
598 - def __new__(cls, name, full_name, filename, values, 599 containing_type=None, options=None, file=None, 600 serialized_start=None, serialized_end=None):
601 _message.Message._CheckCalledFromGeneratedFile() 602 return _message.default_pool.FindEnumTypeByName(full_name)
603
604 - def __init__(self, name, full_name, filename, values, 605 containing_type=None, options=None, file=None, 606 serialized_start=None, serialized_end=None):
607 """Arguments are as described in the attribute description above. 608 609 Note that filename is an obsolete argument, that is not used anymore. 610 Please use file.name to access this as an attribute. 611 """ 612 super(EnumDescriptor, self).__init__( 613 options, 'EnumOptions', name, full_name, file, 614 containing_type, serialized_start=serialized_start, 615 serialized_end=serialized_end) 616 617 self.values = values 618 for value in self.values: 619 value.type = self 620 self.values_by_name = dict((v.name, v) for v in values) 621 self.values_by_number = dict((v.number, v) for v in values)
622
623 - def CopyToProto(self, proto):
624 """Copies this to a descriptor_pb2.EnumDescriptorProto. 625 626 Args: 627 proto: An empty descriptor_pb2.EnumDescriptorProto. 628 """ 629 # This function is overridden to give a better doc comment. 630 super(EnumDescriptor, self).CopyToProto(proto)
631
632 633 -class EnumValueDescriptor(DescriptorBase):
634 635 """Descriptor for a single value within an enum. 636 637 name: (str) Name of this value. 638 index: (int) Dense, 0-indexed index giving the order that this 639 value appears textually within its enum in the .proto file. 640 number: (int) Actual number assigned to this enum value. 641 type: (EnumDescriptor) EnumDescriptor to which this value 642 belongs. Set by EnumDescriptor's constructor if we're 643 passed into one. 644 options: (descriptor_pb2.EnumValueOptions) Enum value options message or 645 None to use default enum value options options. 646 """ 647 648 if _USE_C_DESCRIPTORS: 649 _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor 650
651 - def __new__(cls, name, index, number, type=None, options=None):
652 _message.Message._CheckCalledFromGeneratedFile() 653 # There is no way we can build a complete EnumValueDescriptor with the 654 # given parameters (the name of the Enum is not known, for example). 655 # Fortunately generated files just pass it to the EnumDescriptor() 656 # constructor, which will ignore it, so returning None is good enough. 657 return None
658
659 - def __init__(self, name, index, number, type=None, options=None):
660 """Arguments are as described in the attribute description above.""" 661 super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions') 662 self.name = name 663 self.index = index 664 self.number = number 665 self.type = type
666
667 668 -class OneofDescriptor(DescriptorBase):
669 """Descriptor for a oneof field. 670 671 name: (str) Name of the oneof field. 672 full_name: (str) Full name of the oneof field, including package name. 673 index: (int) 0-based index giving the order of the oneof field inside 674 its containing type. 675 containing_type: (Descriptor) Descriptor of the protocol message 676 type that contains this field. Set by the Descriptor constructor 677 if we're passed into one. 678 fields: (list of FieldDescriptor) The list of field descriptors this 679 oneof can contain. 680 """ 681 682 if _USE_C_DESCRIPTORS: 683 _C_DESCRIPTOR_CLASS = _message.OneofDescriptor 684
685 - def __new__( 686 cls, name, full_name, index, containing_type, fields, options=None):
687 _message.Message._CheckCalledFromGeneratedFile() 688 return _message.default_pool.FindOneofByName(full_name)
689
690 - def __init__( 691 self, name, full_name, index, containing_type, fields, options=None):
692 """Arguments are as described in the attribute description above.""" 693 super(OneofDescriptor, self).__init__(options, 'OneofOptions') 694 self.name = name 695 self.full_name = full_name 696 self.index = index 697 self.containing_type = containing_type 698 self.fields = fields
699
700 701 -class ServiceDescriptor(_NestedDescriptorBase):
702 703 """Descriptor for a service. 704 705 name: (str) Name of the service. 706 full_name: (str) Full name of the service, including package name. 707 index: (int) 0-indexed index giving the order that this services 708 definition appears withing the .proto file. 709 methods: (list of MethodDescriptor) List of methods provided by this 710 service. 711 methods_by_name: (dict str -> MethodDescriptor) Same MethodDescriptor 712 objects as in |methods_by_name|, but indexed by "name" attribute in each 713 MethodDescriptor. 714 options: (descriptor_pb2.ServiceOptions) Service options message or 715 None to use default service options. 716 file: (FileDescriptor) Reference to file info. 717 """ 718 719 if _USE_C_DESCRIPTORS: 720 _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor 721
722 - def __new__(cls, name, full_name, index, methods, options=None, file=None, # pylint: disable=redefined-builtin 723 serialized_start=None, serialized_end=None):
724 _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access 725 return _message.default_pool.FindServiceByName(full_name)
726
727 - def __init__(self, name, full_name, index, methods, options=None, file=None, 728 serialized_start=None, serialized_end=None):
729 super(ServiceDescriptor, self).__init__( 730 options, 'ServiceOptions', name, full_name, file, 731 None, serialized_start=serialized_start, 732 serialized_end=serialized_end) 733 self.index = index 734 self.methods = methods 735 self.methods_by_name = dict((m.name, m) for m in methods) 736 # Set the containing service for each method in this service. 737 for method in self.methods: 738 method.containing_service = self
739
740 - def FindMethodByName(self, name):
741 """Searches for the specified method, and returns its descriptor.""" 742 return self.methods_by_name.get(name, None)
743
744 - def CopyToProto(self, proto):
745 """Copies this to a descriptor_pb2.ServiceDescriptorProto. 746 747 Args: 748 proto: An empty descriptor_pb2.ServiceDescriptorProto. 749 """ 750 # This function is overridden to give a better doc comment. 751 super(ServiceDescriptor, self).CopyToProto(proto)
752
753 754 -class MethodDescriptor(DescriptorBase):
755 756 """Descriptor for a method in a service. 757 758 name: (str) Name of the method within the service. 759 full_name: (str) Full name of method. 760 index: (int) 0-indexed index of the method inside the service. 761 containing_service: (ServiceDescriptor) The service that contains this 762 method. 763 input_type: The descriptor of the message that this method accepts. 764 output_type: The descriptor of the message that this method returns. 765 options: (descriptor_pb2.MethodOptions) Method options message or 766 None to use default method options. 767 """ 768 769 if _USE_C_DESCRIPTORS: 770 _C_DESCRIPTOR_CLASS = _message.MethodDescriptor 771
772 - def __new__(cls, name, full_name, index, containing_service, 773 input_type, output_type, options=None):
774 _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access 775 return _message.default_pool.FindMethodByName(full_name)
776
777 - def __init__(self, name, full_name, index, containing_service, 778 input_type, output_type, options=None):
779 """The arguments are as described in the description of MethodDescriptor 780 attributes above. 781 782 Note that containing_service may be None, and may be set later if necessary. 783 """ 784 super(MethodDescriptor, self).__init__(options, 'MethodOptions') 785 self.name = name 786 self.full_name = full_name 787 self.index = index 788 self.containing_service = containing_service 789 self.input_type = input_type 790 self.output_type = output_type
791
792 793 -class FileDescriptor(DescriptorBase):
794 """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto. 795 796 Note that enum_types_by_name, extensions_by_name, and dependencies 797 fields are only set by the message_factory module, and not by the 798 generated proto code. 799 800 name: name of file, relative to root of source tree. 801 package: name of the package 802 syntax: string indicating syntax of the file (can be "proto2" or "proto3") 803 serialized_pb: (str) Byte string of serialized 804 descriptor_pb2.FileDescriptorProto. 805 dependencies: List of other FileDescriptors this FileDescriptor depends on. 806 public_dependencies: A list of FileDescriptors, subset of the dependencies 807 above, which were declared as "public". 808 message_types_by_name: Dict of message names of their descriptors. 809 enum_types_by_name: Dict of enum names and their descriptors. 810 extensions_by_name: Dict of extension names and their descriptors. 811 services_by_name: Dict of services names and their descriptors. 812 pool: the DescriptorPool this descriptor belongs to. When not passed to the 813 constructor, the global default pool is used. 814 """ 815 816 if _USE_C_DESCRIPTORS: 817 _C_DESCRIPTOR_CLASS = _message.FileDescriptor 818
819 - def __new__(cls, name, package, options=None, serialized_pb=None, 820 dependencies=None, public_dependencies=None, 821 syntax=None, pool=None):
822 # FileDescriptor() is called from various places, not only from generated 823 # files, to register dynamic proto files and messages. 824 if serialized_pb: 825 # TODO(amauryfa): use the pool passed as argument. This will work only 826 # for C++-implemented DescriptorPools. 827 return _message.default_pool.AddSerializedFile(serialized_pb) 828 else: 829 return super(FileDescriptor, cls).__new__(cls)
830
831 - def __init__(self, name, package, options=None, serialized_pb=None, 832 dependencies=None, public_dependencies=None, 833 syntax=None, pool=None):
834 """Constructor.""" 835 super(FileDescriptor, self).__init__(options, 'FileOptions') 836 837 if pool is None: 838 from google.protobuf import descriptor_pool 839 pool = descriptor_pool.Default() 840 self.pool = pool 841 self.message_types_by_name = {} 842 self.name = name 843 self.package = package 844 self.syntax = syntax or "proto2" 845 self.serialized_pb = serialized_pb 846 847 self.enum_types_by_name = {} 848 self.extensions_by_name = {} 849 self.services_by_name = {} 850 self.dependencies = (dependencies or []) 851 self.public_dependencies = (public_dependencies or []) 852 853 if (api_implementation.Type() == 'cpp' and 854 self.serialized_pb is not None): 855 _message.default_pool.AddSerializedFile(self.serialized_pb)
856
857 - def CopyToProto(self, proto):
858 """Copies this to a descriptor_pb2.FileDescriptorProto. 859 860 Args: 861 proto: An empty descriptor_pb2.FileDescriptorProto. 862 """ 863 proto.ParseFromString(self.serialized_pb)
864
865 866 -def _ParseOptions(message, string):
867 """Parses serialized options. 868 869 This helper function is used to parse serialized options in generated 870 proto2 files. It must not be used outside proto2. 871 """ 872 message.ParseFromString(string) 873 return message
874
875 876 -def _ToCamelCase(name):
877 """Converts name to camel-case and returns it.""" 878 capitalize_next = False 879 result = [] 880 881 for c in name: 882 if c == '_': 883 if result: 884 capitalize_next = True 885 elif capitalize_next: 886 result.append(c.upper()) 887 capitalize_next = False 888 else: 889 result += c 890 891 # Lower-case the first letter. 892 if result and result[0].isupper(): 893 result[0] = result[0].lower() 894 return ''.join(result)
895
896 897 -def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True, 898 syntax=None):
899 """Make a protobuf Descriptor given a DescriptorProto protobuf. 900 901 Handles nested descriptors. Note that this is limited to the scope of defining 902 a message inside of another message. Composite fields can currently only be 903 resolved if the message is defined in the same scope as the field. 904 905 Args: 906 desc_proto: The descriptor_pb2.DescriptorProto protobuf message. 907 package: Optional package name for the new message Descriptor (string). 908 build_file_if_cpp: Update the C++ descriptor pool if api matches. 909 Set to False on recursion, so no duplicates are created. 910 syntax: The syntax/semantics that should be used. Set to "proto3" to get 911 proto3 field presence semantics. 912 Returns: 913 A Descriptor for protobuf messages. 914 """ 915 if api_implementation.Type() == 'cpp' and build_file_if_cpp: 916 # The C++ implementation requires all descriptors to be backed by the same 917 # definition in the C++ descriptor pool. To do this, we build a 918 # FileDescriptorProto with the same definition as this descriptor and build 919 # it into the pool. 920 from google.protobuf import descriptor_pb2 921 file_descriptor_proto = descriptor_pb2.FileDescriptorProto() 922 file_descriptor_proto.message_type.add().MergeFrom(desc_proto) 923 924 # Generate a random name for this proto file to prevent conflicts with any 925 # imported ones. We need to specify a file name so the descriptor pool 926 # accepts our FileDescriptorProto, but it is not important what that file 927 # name is actually set to. 928 proto_name = str(uuid.uuid4()) 929 930 if package: 931 file_descriptor_proto.name = os.path.join(package.replace('.', '/'), 932 proto_name + '.proto') 933 file_descriptor_proto.package = package 934 else: 935 file_descriptor_proto.name = proto_name + '.proto' 936 937 _message.default_pool.Add(file_descriptor_proto) 938 result = _message.default_pool.FindFileByName(file_descriptor_proto.name) 939 940 if _USE_C_DESCRIPTORS: 941 return result.message_types_by_name[desc_proto.name] 942 943 full_message_name = [desc_proto.name] 944 if package: full_message_name.insert(0, package) 945 946 # Create Descriptors for enum types 947 enum_types = {} 948 for enum_proto in desc_proto.enum_type: 949 full_name = '.'.join(full_message_name + [enum_proto.name]) 950 enum_desc = EnumDescriptor( 951 enum_proto.name, full_name, None, [ 952 EnumValueDescriptor(enum_val.name, ii, enum_val.number) 953 for ii, enum_val in enumerate(enum_proto.value)]) 954 enum_types[full_name] = enum_desc 955 956 # Create Descriptors for nested types 957 nested_types = {} 958 for nested_proto in desc_proto.nested_type: 959 full_name = '.'.join(full_message_name + [nested_proto.name]) 960 # Nested types are just those defined inside of the message, not all types 961 # used by fields in the message, so no loops are possible here. 962 nested_desc = MakeDescriptor(nested_proto, 963 package='.'.join(full_message_name), 964 build_file_if_cpp=False, 965 syntax=syntax) 966 nested_types[full_name] = nested_desc 967 968 fields = [] 969 for field_proto in desc_proto.field: 970 full_name = '.'.join(full_message_name + [field_proto.name]) 971 enum_desc = None 972 nested_desc = None 973 if field_proto.HasField('type_name'): 974 type_name = field_proto.type_name 975 full_type_name = '.'.join(full_message_name + 976 [type_name[type_name.rfind('.')+1:]]) 977 if full_type_name in nested_types: 978 nested_desc = nested_types[full_type_name] 979 elif full_type_name in enum_types: 980 enum_desc = enum_types[full_type_name] 981 # Else type_name references a non-local type, which isn't implemented 982 field = FieldDescriptor( 983 field_proto.name, full_name, field_proto.number - 1, 984 field_proto.number, field_proto.type, 985 FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), 986 field_proto.label, None, nested_desc, enum_desc, None, False, None, 987 options=field_proto.options, has_default_value=False) 988 fields.append(field) 989 990 desc_name = '.'.join(full_message_name) 991 return Descriptor(desc_proto.name, desc_name, None, None, fields, 992 list(nested_types.values()), list(enum_types.values()), [], 993 options=desc_proto.options)