codekingpro/portable-devtools
114k
1# Protocol Buffers - Google's data interchange format2# Copyright 2008 Google Inc. All rights reserved.3#4# Use of this source code is governed by a BSD-style5# license that can be found in the LICENSE file or at6# https://developers.google.com/open-source/licenses/bsd7 8"""Descriptors essentially contain exactly the information found in a .proto9 10file, in types that make this information accessible in Python.11"""12 13__author__ = 'robinson@google.com (Will Robinson)'14 15import abc16import binascii17import os18import threading19import warnings20 21from google.protobuf.internal import api_implementation22 23_USE_C_DESCRIPTORS = False24if api_implementation.Type() != 'python':25 # pylint: disable=protected-access26 _message = api_implementation._c_module27 # TODO: Remove this import after fix api_implementation28 if _message is None:29 from google.protobuf.pyext import _message30 _USE_C_DESCRIPTORS = True31 32 33class Error(Exception):34 """Base error for this module."""35 36 37class TypeTransformationError(Error):38 """Error transforming between python proto type and corresponding C++ type."""39 40 41if _USE_C_DESCRIPTORS:42 # This metaclass allows to override the behavior of code like43 # isinstance(my_descriptor, FieldDescriptor)44 # and make it return True when the descriptor is an instance of the extension45 # type written in C++.46 class DescriptorMetaclass(type):47 48 def __instancecheck__(cls, obj):49 if super(DescriptorMetaclass, cls).__instancecheck__(obj):50 return True51 if isinstance(obj, cls._C_DESCRIPTOR_CLASS):52 return True53 return False54 55else:56 # The standard metaclass; nothing changes.57 DescriptorMetaclass = abc.ABCMeta58 59 60class _Lock(object):61 """Wrapper class of threading.Lock(), which is allowed by 'with'."""62 63 def __new__(cls):64 self = object.__new__(cls)65 self._lock = threading.Lock() # pylint: disable=protected-access66 return self67 68 def __enter__(self):69 self._lock.acquire()70 71 def __exit__(self, exc_type, exc_value, exc_tb):72 self._lock.release()73 74 75_lock = threading.Lock()76 77 78def _Deprecated(79 name,80 alternative='get/find descriptors from generated code or query the descriptor_pool',81):82 if _Deprecated.count > 0:83 _Deprecated.count -= 184 warnings.warn(85 'Call to deprecated %s, use %s instead.' % (name, alternative),86 category=DeprecationWarning,87 stacklevel=3,88 )89 90 91# These must match the values in descriptor.proto, but we can't use them92# directly because we sometimes need to reference them in feature helpers93# below *during* the build of descriptor.proto.94_FEATURESET_MESSAGE_ENCODING_DELIMITED = 295_FEATURESET_FIELD_PRESENCE_IMPLICIT = 296_FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED = 397_FEATURESET_REPEATED_FIELD_ENCODING_PACKED = 198_FEATURESET_ENUM_TYPE_CLOSED = 299 100# Deprecated warnings will print 100 times at most which should be enough for101# users to notice and do not cause timeout.102_Deprecated.count = 100103 104 105_internal_create_key = object()106 107 108class DescriptorBase(metaclass=DescriptorMetaclass):109 """Descriptors base class.110 111 This class is the base of all descriptor classes. It provides common options112 related functionality.113 114 Attributes:115 has_options: True if the descriptor has non-default options. Usually it is116 not necessary to read this -- just call GetOptions() which will happily117 return the default instance. However, it's sometimes useful for118 efficiency, and also useful inside the protobuf implementation to avoid119 some bootstrapping issues.120 file (FileDescriptor): Reference to file info.121 """122 123 if _USE_C_DESCRIPTORS:124 # The class, or tuple of classes, that are considered as "virtual125 # subclasses" of this descriptor class.126 _C_DESCRIPTOR_CLASS = ()127 128 def __init__(self, file, options, serialized_options, options_class_name):129 """Initialize the descriptor given its options message and the name of the130 131 class of the options message. The name of the class is required in case132 the options message is None and has to be created.133 """134 self._features = None135 self.file = file136 self._original_options = options137 # These two fields are duplicated as a compatibility shim for old gencode138 # that resets them. In 26.x (cl/580304039) we renamed _options to,139 # _loaded_options breaking backwards compatibility.140 self._options = self._loaded_options = None141 self._options_class_name = options_class_name142 self._serialized_options = serialized_options143 144 # Does this descriptor have non-default options?145 self.has_options = (self._original_options is not None) or (146 self._serialized_options is not None147 )148 149 @property150 @abc.abstractmethod151 def _parent(self):152 pass153 154 def _InferLegacyFeatures(self, edition, options, features):155 """Infers features from proto2/proto3 syntax so that editions logic can be used everywhere.156 157 Args:158 edition: The edition to infer features for.159 options: The options for this descriptor that are being processed.160 features: The feature set object to modify with inferred features.161 """162 pass163 164 def _GetFeatures(self):165 if not self._features:166 self._LazyLoadOptions()167 return self._features168 169 def _ResolveFeatures(self, edition, raw_options):170 """Resolves features from the raw options of this descriptor.171 172 Args:173 edition: The edition to use for feature defaults.174 raw_options: The options for this descriptor that are being processed.175 176 Returns:177 A fully resolved feature set for making runtime decisions.178 """179 # pylint: disable=g-import-not-at-top180 from google.protobuf import descriptor_pb2181 182 if self._parent:183 features = descriptor_pb2.FeatureSet()184 features.CopyFrom(self._parent._GetFeatures())185 else:186 features = self.file.pool._CreateDefaultFeatures(edition)187 unresolved = descriptor_pb2.FeatureSet()188 unresolved.CopyFrom(raw_options.features)189 self._InferLegacyFeatures(edition, raw_options, unresolved)190 features.MergeFrom(unresolved)191 192 # Use the feature cache to reduce memory bloat.193 return self.file.pool._InternFeatures(features)194 195 def _LazyLoadOptions(self):196 """Lazily initializes descriptor options towards the end of the build."""197 if self._options and self._loaded_options == self._options:198 # If neither has been reset by gencode, use the cache.199 return200 201 # pylint: disable=g-import-not-at-top202 from google.protobuf import descriptor_pb2203 204 if not hasattr(descriptor_pb2, self._options_class_name):205 raise RuntimeError(206 'Unknown options class name %s!' % self._options_class_name207 )208 options_class = getattr(descriptor_pb2, self._options_class_name)209 features = None210 edition = self.file._edition211 212 if not self.has_options:213 if not self._features:214 features = self._ResolveFeatures(215 descriptor_pb2.Edition.Value(edition), options_class()216 )217 with _lock:218 self._options = self._loaded_options = options_class()219 if not self._features:220 self._features = features221 else:222 if not self._serialized_options:223 options = self._original_options224 else:225 options = _ParseOptions(options_class(), self._serialized_options)226 227 if not self._features:228 features = self._ResolveFeatures(229 descriptor_pb2.Edition.Value(edition), options230 )231 with _lock:232 self._options = self._loaded_options = options233 if not self._features:234 self._features = features235 if options.HasField('features'):236 options.ClearField('features')237 if not options.SerializeToString():238 self._options = self._loaded_options = options_class()239 self.has_options = False240 241 def GetOptions(self):242 """Retrieves descriptor options.243 244 Returns:245 The options set on this descriptor.246 """247 # If either has been reset by gencode, reload options.248 if not self._options or not self._loaded_options:249 self._LazyLoadOptions()250 return self._options251 252 253class _NestedDescriptorBase(DescriptorBase):254 """Common class for descriptors that can be nested."""255 256 def __init__(257 self,258 options,259 options_class_name,260 name,261 full_name,262 file,263 containing_type,264 serialized_start=None,265 serialized_end=None,266 serialized_options=None,267 ):268 """Constructor.269 270 Args:271 options: Protocol message options or None to use default message options.272 options_class_name (str): The class name of the above options.273 name (str): Name of this protocol message type.274 full_name (str): Fully-qualified name of this protocol message type, which275 will include protocol "package" name and the name of any enclosing276 types.277 containing_type: if provided, this is a nested descriptor, with this278 descriptor as parent, otherwise None.279 serialized_start: The start index (inclusive) in block in the280 file.serialized_pb that describes this descriptor.281 serialized_end: The end index (exclusive) in block in the282 file.serialized_pb that describes this descriptor.283 serialized_options: Protocol message serialized options or None.284 """285 super(_NestedDescriptorBase, self).__init__(286 file, options, serialized_options, options_class_name287 )288 289 self.name = name290 # TODO: Add function to calculate full_name instead of having it in291 # memory?292 self.full_name = full_name293 self.containing_type = containing_type294 295 self._serialized_start = serialized_start296 self._serialized_end = serialized_end297 298 def CopyToProto(self, proto):299 """Copies this to the matching proto in descriptor_pb2.300 301 Args:302 proto: An empty proto instance from descriptor_pb2.303 304 Raises:305 Error: If self couldn't be serialized, due to to few constructor306 arguments.307 """308 if (309 self.file is not None310 and self._serialized_start is not None311 and self._serialized_end is not None312 ):313 proto.ParseFromString(314 self.file.serialized_pb[self._serialized_start : self._serialized_end]315 )316 else:317 raise Error('Descriptor does not contain serialization.')318 319 320class Descriptor(_NestedDescriptorBase):321 """Descriptor for a protocol message type.322 323 Attributes:324 name (str): Name of this protocol message type.325 full_name (str): Fully-qualified name of this protocol message type, which326 will include protocol "package" name and the name of any enclosing327 types.328 containing_type (Descriptor): Reference to the descriptor of the type329 containing us, or None if this is top-level.330 fields (list[FieldDescriptor]): Field descriptors for all fields in this331 type.332 fields_by_number (dict(int, FieldDescriptor)): Same333 :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed by334 "number" attribute in each FieldDescriptor.335 fields_by_name (dict(str, FieldDescriptor)): Same :class:`FieldDescriptor`336 objects as in :attr:`fields`, but indexed by "name" attribute in each337 :class:`FieldDescriptor`.338 nested_types (list[Descriptor]): Descriptor references for all protocol339 message types nested within this one.340 nested_types_by_name (dict(str, Descriptor)): Same Descriptor objects as341 in :attr:`nested_types`, but indexed by "name" attribute in each342 Descriptor.343 enum_types (list[EnumDescriptor]): :class:`EnumDescriptor` references for344 all enums contained within this type.345 enum_types_by_name (dict(str, EnumDescriptor)): Same346 :class:`EnumDescriptor` objects as in :attr:`enum_types`, but indexed by347 "name" attribute in each EnumDescriptor.348 enum_values_by_name (dict(str, EnumValueDescriptor)): Dict mapping from349 enum value name to :class:`EnumValueDescriptor` for that value.350 extensions (list[FieldDescriptor]): All extensions defined directly within351 this message type (NOT within a nested type).352 extensions_by_name (dict(str, FieldDescriptor)): Same FieldDescriptor353 objects as :attr:`extensions`, but indexed by "name" attribute of each354 FieldDescriptor.355 is_extendable (bool): Does this type define any extension ranges?356 oneofs (list[OneofDescriptor]): The list of descriptors for oneof fields357 in this message.358 oneofs_by_name (dict(str, OneofDescriptor)): Same objects as in359 :attr:`oneofs`, but indexed by "name" attribute.360 file (FileDescriptor): Reference to file descriptor.361 is_map_entry: If the message type is a map entry.362 """363 364 if _USE_C_DESCRIPTORS:365 _C_DESCRIPTOR_CLASS = _message.Descriptor366 367 def __new__(368 cls,369 name=None,370 full_name=None,371 filename=None,372 containing_type=None,373 fields=None,374 nested_types=None,375 enum_types=None,376 extensions=None,377 options=None,378 serialized_options=None,379 is_extendable=True,380 extension_ranges=None,381 oneofs=None,382 file=None, # pylint: disable=redefined-builtin383 serialized_start=None,384 serialized_end=None,385 syntax=None,386 is_map_entry=False,387 create_key=None,388 ):389 _message.Message._CheckCalledFromGeneratedFile()390 return _message.default_pool.FindMessageTypeByName(full_name)391 392 # NOTE: The file argument redefining a builtin is nothing we can393 # fix right now since we don't know how many clients already rely on the394 # name of the argument.395 def __init__(396 self,397 name,398 full_name,399 filename,400 containing_type,401 fields,402 nested_types,403 enum_types,404 extensions,405 options=None,406 serialized_options=None,407 is_extendable=True,408 extension_ranges=None,409 oneofs=None,410 file=None,411 serialized_start=None,412 serialized_end=None, # pylint: disable=redefined-builtin413 syntax=None,414 is_map_entry=False,415 create_key=None,416 ):417 """Arguments to __init__() are as described in the description418 419 of Descriptor fields above.420 421 Note that filename is an obsolete argument, that is not used anymore.422 Please use file.name to access this as an attribute.423 """424 if create_key is not _internal_create_key:425 _Deprecated('create function Descriptor()')426 427 super(Descriptor, self).__init__(428 options,429 'MessageOptions',430 name,431 full_name,432 file,433 containing_type,434 serialized_start=serialized_start,435 serialized_end=serialized_end,436 serialized_options=serialized_options,437 )438 439 # We have fields in addition to fields_by_name and fields_by_number,440 # so that:441 # 1. Clients can index fields by "order in which they're listed."442 # 2. Clients can easily iterate over all fields with the terse443 # syntax: for f in descriptor.fields: ...444 self.fields = fields445 for field in self.fields:446 field.containing_type = self447 field.file = file448 self.fields_by_number = dict((f.number, f) for f in fields)449 self.fields_by_name = dict((f.name, f) for f in fields)450 self._fields_by_camelcase_name = None451 452 self.nested_types = nested_types453 for nested_type in nested_types:454 nested_type.containing_type = self455 self.nested_types_by_name = dict((t.name, t) for t in nested_types)456 457 self.enum_types = enum_types458 for enum_type in self.enum_types:459 enum_type.containing_type = self460 self.enum_types_by_name = dict((t.name, t) for t in enum_types)461 self.enum_values_by_name = dict(462 (v.name, v) for t in enum_types for v in t.values463 )464 465 self.extensions = extensions466 for extension in self.extensions:467 extension.extension_scope = self468 self.extensions_by_name = dict((f.name, f) for f in extensions)469 self.is_extendable = is_extendable470 self.extension_ranges = extension_ranges471 self.oneofs = oneofs if oneofs is not None else []472 self.oneofs_by_name = dict((o.name, o) for o in self.oneofs)473 for oneof in self.oneofs:474 oneof.containing_type = self475 oneof.file = file476 self._is_map_entry = is_map_entry477 478 @property479 def _parent(self):480 return self.containing_type or self.file481 482 @property483 def fields_by_camelcase_name(self):484 """Same FieldDescriptor objects as in :attr:`fields`, but indexed by485 486 :attr:`FieldDescriptor.camelcase_name`.487 """488 if self._fields_by_camelcase_name is None:489 self._fields_by_camelcase_name = dict(490 (f.camelcase_name, f) for f in self.fields491 )492 return self._fields_by_camelcase_name493 494 def EnumValueName(self, enum, value):495 """Returns the string name of an enum value.496 497 This is just a small helper method to simplify a common operation.498 499 Args:500 enum: string name of the Enum.501 value: int, value of the enum.502 503 Returns:504 string name of the enum value.505 506 Raises:507 KeyError if either the Enum doesn't exist or the value is not a valid508 value for the enum.509 """510 return self.enum_types_by_name[enum].values_by_number[value].name511 512 def CopyToProto(self, proto):513 """Copies this to a descriptor_pb2.DescriptorProto.514 515 Args:516 proto: An empty descriptor_pb2.DescriptorProto.517 """518 # This function is overridden to give a better doc comment.519 super(Descriptor, self).CopyToProto(proto)520 521 522# TODO: We should have aggressive checking here,523# for example:524# * If you specify a repeated field, you should not be allowed525# to specify a default value.526# * [Other examples here as needed].527#528# TODO: for this and other *Descriptor classes, we529# might also want to lock things down aggressively (e.g.,530# prevent clients from setting the attributes). Having531# stronger invariants here in general will reduce the number532# of runtime checks we must do in reflection.py...533class FieldDescriptor(DescriptorBase):534 """Descriptor for a single field in a .proto file.535 536 Attributes:537 name (str): Name of this field, exactly as it appears in .proto.538 full_name (str): Name of this field, including containing scope. This is539 particularly relevant for extensions.540 index (int): Dense, 0-indexed index giving the order that this field541 textually appears within its message in the .proto file.542 number (int): Tag number declared for this field in the .proto file.543 type (int): (One of the TYPE_* constants below) Declared type.544 cpp_type (int): (One of the CPPTYPE_* constants below) C++ type used to545 represent this field.546 label (int): (One of the LABEL_* constants below) Tells whether this field547 is optional, required, or repeated.548 has_default_value (bool): True if this field has a default value defined,549 otherwise false.550 default_value (Varies): Default value of this field. Only meaningful for551 non-repeated scalar fields. Repeated fields should always set this to [],552 and non-repeated composite fields should always set this to None.553 containing_type (Descriptor): Descriptor of the protocol message type that554 contains this field. Set by the Descriptor constructor if we're passed555 into one. Somewhat confusingly, for extension fields, this is the556 descriptor of the EXTENDED message, not the descriptor of the message557 containing this field. (See is_extension and extension_scope below).558 message_type (Descriptor): If a composite field, a descriptor of the message559 type contained in this field. Otherwise, this is None.560 enum_type (EnumDescriptor): If this field contains an enum, a descriptor of561 that enum. Otherwise, this is None.562 is_extension: True iff this describes an extension field.563 extension_scope (Descriptor): Only meaningful if is_extension is True. Gives564 the message that immediately contains this extension field. Will be None565 iff we're a top-level (file-level) extension field.566 options (descriptor_pb2.FieldOptions): Protocol message field options or567 None to use default field options.568 containing_oneof (OneofDescriptor): If the field is a member of a oneof569 union, contains its descriptor. Otherwise, None.570 file (FileDescriptor): Reference to file descriptor.571 """572 573 # Must be consistent with C++ FieldDescriptor::Type enum in574 # descriptor.h.575 #576 # TODO: Find a way to eliminate this repetition.577 TYPE_DOUBLE = 1578 TYPE_FLOAT = 2579 TYPE_INT64 = 3580 TYPE_UINT64 = 4581 TYPE_INT32 = 5582 TYPE_FIXED64 = 6583 TYPE_FIXED32 = 7584 TYPE_BOOL = 8585 TYPE_STRING = 9586 TYPE_GROUP = 10587 TYPE_MESSAGE = 11588 TYPE_BYTES = 12589 TYPE_UINT32 = 13590 TYPE_ENUM = 14591 TYPE_SFIXED32 = 15592 TYPE_SFIXED64 = 16593 TYPE_SINT32 = 17594 TYPE_SINT64 = 18595 MAX_TYPE = 18596 597 # Must be consistent with C++ FieldDescriptor::CppType enum in598 # descriptor.h.599 #600 # TODO: Find a way to eliminate this repetition.601 CPPTYPE_INT32 = 1602 CPPTYPE_INT64 = 2603 CPPTYPE_UINT32 = 3604 CPPTYPE_UINT64 = 4605 CPPTYPE_DOUBLE = 5606 CPPTYPE_FLOAT = 6607 CPPTYPE_BOOL = 7608 CPPTYPE_ENUM = 8609 CPPTYPE_STRING = 9610 CPPTYPE_MESSAGE = 10611 MAX_CPPTYPE = 10612 613 _PYTHON_TO_CPP_PROTO_TYPE_MAP = {614 TYPE_DOUBLE: CPPTYPE_DOUBLE,615 TYPE_FLOAT: CPPTYPE_FLOAT,616 TYPE_ENUM: CPPTYPE_ENUM,617 TYPE_INT64: CPPTYPE_INT64,618 TYPE_SINT64: CPPTYPE_INT64,619 TYPE_SFIXED64: CPPTYPE_INT64,620 TYPE_UINT64: CPPTYPE_UINT64,621 TYPE_FIXED64: CPPTYPE_UINT64,622 TYPE_INT32: CPPTYPE_INT32,623 TYPE_SFIXED32: CPPTYPE_INT32,624 TYPE_SINT32: CPPTYPE_INT32,625 TYPE_UINT32: CPPTYPE_UINT32,626 TYPE_FIXED32: CPPTYPE_UINT32,627 TYPE_BYTES: CPPTYPE_STRING,628 TYPE_STRING: CPPTYPE_STRING,629 TYPE_BOOL: CPPTYPE_BOOL,630 TYPE_MESSAGE: CPPTYPE_MESSAGE,631 TYPE_GROUP: CPPTYPE_MESSAGE,632 }633 634 # Must be consistent with C++ FieldDescriptor::Label enum in635 # descriptor.h.636 #637 # TODO: Find a way to eliminate this repetition.638 LABEL_OPTIONAL = 1639 LABEL_REQUIRED = 2640 LABEL_REPEATED = 3641 MAX_LABEL = 3642 643 # Must be consistent with C++ constants kMaxNumber, kFirstReservedNumber,644 # and kLastReservedNumber in descriptor.h645 MAX_FIELD_NUMBER = (1 << 29) - 1646 FIRST_RESERVED_FIELD_NUMBER = 19000647 LAST_RESERVED_FIELD_NUMBER = 19999648 649 if _USE_C_DESCRIPTORS:650 _C_DESCRIPTOR_CLASS = _message.FieldDescriptor651 652 def __new__(653 cls,654 name,655 full_name,656 index,657 number,658 type,659 cpp_type,660 label,661 default_value,662 message_type,663 enum_type,664 containing_type,665 is_extension,666 extension_scope,667 options=None,668 serialized_options=None,669 has_default_value=True,670 containing_oneof=None,671 json_name=None,672 file=None,673 create_key=None,674 ): # pylint: disable=redefined-builtin675 _message.Message._CheckCalledFromGeneratedFile()676 if is_extension:677 return _message.default_pool.FindExtensionByName(full_name)678 else:679 return _message.default_pool.FindFieldByName(full_name)680 681 def __init__(682 self,683 name,684 full_name,685 index,686 number,687 type,688 cpp_type,689 label,690 default_value,691 message_type,692 enum_type,693 containing_type,694 is_extension,695 extension_scope,696 options=None,697 serialized_options=None,698 has_default_value=True,699 containing_oneof=None,700 json_name=None,701 file=None,702 create_key=None,703 ): # pylint: disable=redefined-builtin704 """The arguments are as described in the description of FieldDescriptor705 706 attributes above.707 708 Note that containing_type may be None, and may be set later if necessary709 (to deal with circular references between message types, for example).710 Likewise for extension_scope.711 """712 if create_key is not _internal_create_key:713 _Deprecated('create function FieldDescriptor()')714 715 super(FieldDescriptor, self).__init__(716 file, options, serialized_options, 'FieldOptions'717 )718 self.name = name719 self.full_name = full_name720 self._camelcase_name = None721 if json_name is None:722 self.json_name = _ToJsonName(name)723 else:724 self.json_name = json_name725 self.index = index726 self.number = number727 self._type = type728 self.cpp_type = cpp_type729 self._label = label730 self.has_default_value = has_default_value731 self.default_value = default_value732 self.containing_type = containing_type733 self.message_type = message_type734 self.enum_type = enum_type735 self.is_extension = is_extension736 self.extension_scope = extension_scope737 self.containing_oneof = containing_oneof738 if api_implementation.Type() == 'python':739 self._cdescriptor = None740 else:741 if is_extension:742 self._cdescriptor = _message.default_pool.FindExtensionByName(full_name)743 else:744 self._cdescriptor = _message.default_pool.FindFieldByName(full_name)745 746 @property747 def _parent(self):748 if self.containing_oneof:749 return self.containing_oneof750 if self.is_extension:751 return self.extension_scope or self.file752 return self.containing_type753 754 def _InferLegacyFeatures(self, edition, options, features):755 # pylint: disable=g-import-not-at-top756 from google.protobuf import descriptor_pb2757 758 if edition >= descriptor_pb2.Edition.EDITION_2023:759 return760 761 if self._label == FieldDescriptor.LABEL_REQUIRED:762 features.field_presence = (763 descriptor_pb2.FeatureSet.FieldPresence.LEGACY_REQUIRED764 )765 766 if self._type == FieldDescriptor.TYPE_GROUP:767 features.message_encoding = (768 descriptor_pb2.FeatureSet.MessageEncoding.DELIMITED769 )770 771 if options.HasField('packed'):772 features.repeated_field_encoding = (773 descriptor_pb2.FeatureSet.RepeatedFieldEncoding.PACKED774 if options.packed775 else descriptor_pb2.FeatureSet.RepeatedFieldEncoding.EXPANDED776 )777 778 @property779 def type(self):780 if (781 self._GetFeatures().message_encoding782 == _FEATURESET_MESSAGE_ENCODING_DELIMITED783 and self.message_type784 and not self.message_type.GetOptions().map_entry785 and not self.containing_type.GetOptions().map_entry786 ):787 return FieldDescriptor.TYPE_GROUP788 return self._type789 790 @type.setter791 def type(self, val):792 self._type = val793 794 @property795 def label(self):796 _Deprecated('label property', 'is_required or is_repeated properties')797 798 if (799 self._GetFeatures().field_presence800 == _FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED801 ):802 return FieldDescriptor.LABEL_REQUIRED803 return self._label804 805 @property806 def is_required(self):807 """Returns if the field is required."""808 return (809 self._GetFeatures().field_presence810 == _FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED811 )812 813 @property814 def is_repeated(self):815 """Returns if the field is repeated."""816 return self._label == FieldDescriptor.LABEL_REPEATED817 818 @property819 def camelcase_name(self):820 """Camelcase name of this field.821 822 Returns:823 str: the name in CamelCase.824 """825 if self._camelcase_name is None:826 self._camelcase_name = _ToCamelCase(self.name)827 return self._camelcase_name828 829 @property830 def has_presence(self):831 """Whether the field distinguishes between unpopulated and default values.832 833 Raises:834 RuntimeError: singular field that is not linked with message nor file.835 """836 if self.is_repeated:837 return False838 if (839 self.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE840 or self.is_extension841 or self.containing_oneof842 ):843 return True844 845 return (846 self._GetFeatures().field_presence847 != _FEATURESET_FIELD_PRESENCE_IMPLICIT848 )849 850 @property851 def is_packed(self):852 """Returns if the field is packed."""853 if not self.is_repeated:854 return False855 field_type = self.type856 if (857 field_type == FieldDescriptor.TYPE_STRING858 or field_type == FieldDescriptor.TYPE_GROUP859 or field_type == FieldDescriptor.TYPE_MESSAGE860 or field_type == FieldDescriptor.TYPE_BYTES861 ):862 return False863 864 return (865 self._GetFeatures().repeated_field_encoding866 == _FEATURESET_REPEATED_FIELD_ENCODING_PACKED867 )868 869 @staticmethod870 def ProtoTypeToCppProtoType(proto_type):871 """Converts from a Python proto type to a C++ Proto Type.872 873 The Python ProtocolBuffer classes specify both the 'Python' datatype and the874 'C++' datatype - and they're not the same. This helper method should875 translate from one to another.876 877 Args:878 proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*)879 880 Returns:881 int: descriptor.FieldDescriptor.CPPTYPE_*, the C++ type.882 Raises:883 TypeTransformationError: when the Python proto type isn't known.884 """885 try:886 return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type]887 except KeyError:888 raise TypeTransformationError('Unknown proto_type: %s' % proto_type)889 890 891class EnumDescriptor(_NestedDescriptorBase):892 """Descriptor for an enum defined in a .proto file.893 894 Attributes:895 name (str): Name of the enum type.896 full_name (str): Full name of the type, including package name and any897 enclosing type(s).898 values (list[EnumValueDescriptor]): List of the values in this enum.899 values_by_name (dict(str, EnumValueDescriptor)): Same as :attr:`values`, but900 indexed by the "name" field of each EnumValueDescriptor.901 values_by_number (dict(int, EnumValueDescriptor)): Same as :attr:`values`,902 but indexed by the "number" field of each EnumValueDescriptor.903 containing_type (Descriptor): Descriptor of the immediate containing type of904 this enum, or None if this is an enum defined at the top level in a .proto905 file. Set by Descriptor's constructor if we're passed into one.906 file (FileDescriptor): Reference to file descriptor.907 options (descriptor_pb2.EnumOptions): Enum options message or None to use908 default enum options.909 """910 911 if _USE_C_DESCRIPTORS:912 _C_DESCRIPTOR_CLASS = _message.EnumDescriptor913 914 def __new__(915 cls,916 name,917 full_name,918 filename,919 values,920 containing_type=None,921 options=None,922 serialized_options=None,923 file=None, # pylint: disable=redefined-builtin924 serialized_start=None,925 serialized_end=None,926 create_key=None,927 ):928 _message.Message._CheckCalledFromGeneratedFile()929 return _message.default_pool.FindEnumTypeByName(full_name)930 931 def __init__(932 self,933 name,934 full_name,935 filename,936 values,937 containing_type=None,938 options=None,939 serialized_options=None,940 file=None, # pylint: disable=redefined-builtin941 serialized_start=None,942 serialized_end=None,943 create_key=None,944 ):945 """Arguments are as described in the attribute description above.946 947 Note that filename is an obsolete argument, that is not used anymore.948 Please use file.name to access this as an attribute.949 """950 if create_key is not _internal_create_key:951 _Deprecated('create function EnumDescriptor()')952 953 super(EnumDescriptor, self).__init__(954 options,955 'EnumOptions',956 name,957 full_name,958 file,959 containing_type,960 serialized_start=serialized_start,961 serialized_end=serialized_end,962 serialized_options=serialized_options,963 )964 965 self.values = values966 for value in self.values:967 value.file = file968 value.type = self969 self.values_by_name = dict((v.name, v) for v in values)970 # Values are reversed to ensure that the first alias is retained.971 self.values_by_number = dict((v.number, v) for v in reversed(values))972 973 @property974 def _parent(self):975 return self.containing_type or self.file976 977 @property978 def is_closed(self):979 """Returns true whether this is a "closed" enum.980 981 This means that it:982 - Has a fixed set of values, rather than being equivalent to an int32.983 - Encountering values not in this set causes them to be treated as unknown984 fields.985 - The first value (i.e., the default) may be nonzero.986 987 WARNING: Some runtimes currently have a quirk where non-closed enums are988 treated as closed when used as the type of fields defined in a989 `syntax = proto2;` file. This quirk is not present in all runtimes; as of990 writing, we know that:991 992 - C++, Java, and C++-based Python share this quirk.993 - UPB and UPB-based Python do not.994 - PHP and Ruby treat all enums as open regardless of declaration.995 996 Care should be taken when using this function to respect the target997 runtime's enum handling quirks.998 """999 return self._GetFeatures().enum_type == _FEATURESET_ENUM_TYPE_CLOSED1000 1001 def CopyToProto(self, proto):1002 """Copies this to a descriptor_pb2.EnumDescriptorProto.1003 1004 Args:1005 proto (descriptor_pb2.EnumDescriptorProto): An empty descriptor proto.1006 """1007 # This function is overridden to give a better doc comment.1008 super(EnumDescriptor, self).CopyToProto(proto)1009 1010 1011class EnumValueDescriptor(DescriptorBase):1012 """Descriptor for a single value within an enum.1013 1014 Attributes:1015 name (str): Name of this value.1016 index (int): Dense, 0-indexed index giving the order that this value appears1017 textually within its enum in the .proto file.1018 number (int): Actual number assigned to this enum value.1019 type (EnumDescriptor): :class:`EnumDescriptor` to which this value belongs.1020 Set by :class:`EnumDescriptor`'s constructor if we're passed into one.1021 options (descriptor_pb2.EnumValueOptions): Enum value options message or1022 None to use default enum value options options.1023 """1024 1025 if _USE_C_DESCRIPTORS:1026 _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor1027 1028 def __new__(1029 cls,1030 name,1031 index,1032 number,1033 type=None, # pylint: disable=redefined-builtin1034 options=None,1035 serialized_options=None,1036 create_key=None,1037 ):1038 _message.Message._CheckCalledFromGeneratedFile()1039 # There is no way we can build a complete EnumValueDescriptor with the1040 # given parameters (the name of the Enum is not known, for example).1041 # Fortunately generated files just pass it to the EnumDescriptor()1042 # constructor, which will ignore it, so returning None is good enough.1043 return None1044 1045 def __init__(1046 self,1047 name,1048 index,1049 number,1050 type=None, # pylint: disable=redefined-builtin1051 options=None,1052 serialized_options=None,1053 create_key=None,1054 ):1055 """Arguments are as described in the attribute description above."""1056 if create_key is not _internal_create_key:1057 _Deprecated('create function EnumValueDescriptor()')1058 1059 super(EnumValueDescriptor, self).__init__(1060 type.file if type else None,1061 options,1062 serialized_options,1063 'EnumValueOptions',1064 )1065 self.name = name1066 self.index = index1067 self.number = number1068 self.type = type1069 1070 @property1071 def _parent(self):1072 return self.type1073 1074 1075class OneofDescriptor(DescriptorBase):1076 """Descriptor for a oneof field.1077 1078 Attributes:1079 name (str): Name of the oneof field.1080 full_name (str): Full name of the oneof field, including package name.1081 index (int): 0-based index giving the order of the oneof field inside its1082 containing type.1083 containing_type (Descriptor): :class:`Descriptor` of the protocol message1084 type that contains this field. Set by the :class:`Descriptor` constructor1085 if we're passed into one.1086 fields (list[FieldDescriptor]): The list of field descriptors this oneof can1087 contain.1088 """1089 1090 if _USE_C_DESCRIPTORS:1091 _C_DESCRIPTOR_CLASS = _message.OneofDescriptor1092 1093 def __new__(1094 cls,1095 name,1096 full_name,1097 index,1098 containing_type,1099 fields,1100 options=None,1101 serialized_options=None,1102 create_key=None,1103 ):1104 _message.Message._CheckCalledFromGeneratedFile()1105 return _message.default_pool.FindOneofByName(full_name)1106 1107 def __init__(1108 self,1109 name,1110 full_name,1111 index,1112 containing_type,1113 fields,1114 options=None,1115 serialized_options=None,1116 create_key=None,1117 ):1118 """Arguments are as described in the attribute description above."""1119 if create_key is not _internal_create_key:1120 _Deprecated('create function OneofDescriptor()')1121 1122 super(OneofDescriptor, self).__init__(1123 containing_type.file if containing_type else None,1124 options,1125 serialized_options,1126 'OneofOptions',1127 )1128 self.name = name1129 self.full_name = full_name1130 self.index = index1131 self.containing_type = containing_type1132 self.fields = fields1133 1134 @property1135 def _parent(self):1136 return self.containing_type1137 1138 1139class ServiceDescriptor(_NestedDescriptorBase):1140 """Descriptor for a service.1141 1142 Attributes:1143 name (str): Name of the service.1144 full_name (str): Full name of the service, including package name.1145 index (int): 0-indexed index giving the order that this services definition1146 appears within the .proto file.1147 methods (list[MethodDescriptor]): List of methods provided by this service.1148 methods_by_name (dict(str, MethodDescriptor)): Same1149 :class:`MethodDescriptor` objects as in :attr:`methods_by_name`, but1150 indexed by "name" attribute in each :class:`MethodDescriptor`.1151 options (descriptor_pb2.ServiceOptions): Service options message or None to1152 use default service options.1153 file (FileDescriptor): Reference to file info.1154 """1155 1156 if _USE_C_DESCRIPTORS:1157 _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor1158 1159 def __new__(1160 cls,1161 name=None,1162 full_name=None,1163 index=None,1164 methods=None,1165 options=None,1166 serialized_options=None,1167 file=None, # pylint: disable=redefined-builtin1168 serialized_start=None,1169 serialized_end=None,1170 create_key=None,1171 ):1172 _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access1173 return _message.default_pool.FindServiceByName(full_name)1174 1175 def __init__(1176 self,1177 name,1178 full_name,1179 index,1180 methods,1181 options=None,1182 serialized_options=None,1183 file=None, # pylint: disable=redefined-builtin1184 serialized_start=None,1185 serialized_end=None,1186 create_key=None,1187 ):1188 if create_key is not _internal_create_key:1189 _Deprecated('create function ServiceDescriptor()')1190 1191 super(ServiceDescriptor, self).__init__(1192 options,1193 'ServiceOptions',1194 name,1195 full_name,1196 file,1197 None,1198 serialized_start=serialized_start,1199 serialized_end=serialized_end,1200 serialized_options=serialized_options,