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