1# Protocol Buffers - Google's data interchange format 
    2# Copyright 2008 Google Inc.  All rights reserved. 
    3# 
    4# Use of this source code is governed by a BSD-style 
    5# license that can be found in the LICENSE file or at 
    6# https://developers.google.com/open-source/licenses/bsd 
    7 
    8"""Descriptors essentially contain exactly the information found in a .proto 
    9 
    10file, in types that make this information accessible in Python. 
    11""" 
    12 
    13__author__ = 'robinson@google.com (Will Robinson)' 
    14 
    15import abc 
    16import binascii 
    17import os 
    18import threading 
    19import warnings 
    20 
    21from google.protobuf.internal import api_implementation 
    22 
    23_USE_C_DESCRIPTORS = False 
    24if api_implementation.Type() != 'python': 
    25  # pylint: disable=protected-access 
    26  _message = api_implementation._c_module 
    27  # TODO: Remove this import after fix api_implementation 
    28  if _message is None: 
    29    from google.protobuf.pyext import _message 
    30  _USE_C_DESCRIPTORS = True 
    31 
    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 like 
    43  #     isinstance(my_descriptor, FieldDescriptor) 
    44  # and make it return True when the descriptor is an instance of the extension 
    45  # type written in C++. 
    46  class DescriptorMetaclass(type): 
    47 
    48    def __instancecheck__(cls, obj): 
    49      if super(DescriptorMetaclass, cls).__instancecheck__(obj): 
    50        return True 
    51      if isinstance(obj, cls._C_DESCRIPTOR_CLASS): 
    52        return True 
    53      return False 
    54 
    55else: 
    56  # The standard metaclass; nothing changes. 
    57  DescriptorMetaclass = abc.ABCMeta 
    58 
    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-access 
    66    return self 
    67 
    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 -= 1 
    84    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 them 
    92# directly because we sometimes need to reference them in feature helpers 
    93# below *during* the build of descriptor.proto. 
    94_FEATURESET_MESSAGE_ENCODING_DELIMITED = 2 
    95_FEATURESET_FIELD_PRESENCE_IMPLICIT = 2 
    96_FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED = 3 
    97_FEATURESET_REPEATED_FIELD_ENCODING_PACKED = 1 
    98_FEATURESET_ENUM_TYPE_CLOSED = 2 
    99 
    100# Deprecated warnings will print 100 times at most which should be enough for 
    101# users to notice and do not cause timeout. 
    102_Deprecated.count = 100 
    103 
    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 options 
    112  related functionality. 
    113 
    114  Attributes: 
    115    has_options:  True if the descriptor has non-default options.  Usually it is 
    116      not necessary to read this -- just call GetOptions() which will happily 
    117      return the default instance.  However, it's sometimes useful for 
    118      efficiency, and also useful inside the protobuf implementation to avoid 
    119      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 "virtual 
    125    # 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 the 
    130 
    131    class of the options message. The name of the class is required in case 
    132    the options message is None and has to be created. 
    133    """ 
    134    self._features = None 
    135    self.file = file 
    136    self._original_options = options 
    137    # These two fields are duplicated as a compatibility shim for old gencode 
    138    # that resets them.  In 26.x (cl/580304039) we renamed _options to, 
    139    # _loaded_options breaking backwards compatibility. 
    140    self._options = self._loaded_options = None 
    141    self._options_class_name = options_class_name 
    142    self._serialized_options = serialized_options 
    143 
    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 None 
    147    ) 
    148 
    149  @property 
    150  @abc.abstractmethod 
    151  def _parent(self): 
    152    pass 
    153 
    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    pass 
    163 
    164  def _GetFeatures(self): 
    165    if not self._features: 
    166      self._LazyLoadOptions() 
    167    return self._features 
    168 
    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-top 
    180    from google.protobuf import descriptor_pb2 
    181 
    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      return 
    200 
    201    # pylint: disable=g-import-not-at-top 
    202    from google.protobuf import descriptor_pb2 
    203 
    204    if not hasattr(descriptor_pb2, self._options_class_name): 
    205      raise RuntimeError( 
    206          'Unknown options class name %s!' % self._options_class_name 
    207      ) 
    208    options_class = getattr(descriptor_pb2, self._options_class_name) 
    209    features = None 
    210    edition = self.file._edition 
    211 
    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 = features 
    221    else: 
    222      if not self._serialized_options: 
    223        options = self._original_options 
    224      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), options 
    230        ) 
    231      with _lock: 
    232        self._options = self._loaded_options = options 
    233        if not self._features: 
    234          self._features = features 
    235        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 = False 
    240 
    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._options 
    251 
    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, which 
    275        will include protocol "package" name and the name of any enclosing 
    276        types. 
    277      containing_type: if provided, this is a nested descriptor, with this 
    278        descriptor as parent, otherwise None. 
    279      serialized_start: The start index (inclusive) in block in the 
    280        file.serialized_pb that describes this descriptor. 
    281      serialized_end: The end index (exclusive) in block in the 
    282        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_name 
    287    ) 
    288 
    289    self.name = name 
    290    # TODO: Add function to calculate full_name instead of having it in 
    291    #             memory? 
    292    self.full_name = full_name 
    293    self.containing_type = containing_type 
    294 
    295    self._serialized_start = serialized_start 
    296    self._serialized_end = serialized_end 
    297 
    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 constructor 
    306        arguments. 
    307    """ 
    308    if ( 
    309        self.file is not None 
    310        and self._serialized_start is not None 
    311        and self._serialized_end is not None 
    312    ): 
    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, which 
    326        will include protocol "package" name and the name of any enclosing 
    327        types. 
    328      containing_type (Descriptor): Reference to the descriptor of the type 
    329        containing us, or None if this is top-level. 
    330      fields (list[FieldDescriptor]): Field descriptors for all fields in this 
    331        type. 
    332      fields_by_number (dict(int, FieldDescriptor)): Same 
    333        :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed by 
    334        "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 each 
    337        :class:`FieldDescriptor`. 
    338      nested_types (list[Descriptor]): Descriptor references for all protocol 
    339        message types nested within this one. 
    340      nested_types_by_name (dict(str, Descriptor)): Same Descriptor objects as 
    341        in :attr:`nested_types`, but indexed by "name" attribute in each 
    342        Descriptor. 
    343      enum_types (list[EnumDescriptor]): :class:`EnumDescriptor` references for 
    344        all enums contained within this type. 
    345      enum_types_by_name (dict(str, EnumDescriptor)): Same 
    346        :class:`EnumDescriptor` objects as in :attr:`enum_types`, but indexed by 
    347        "name" attribute in each EnumDescriptor. 
    348      enum_values_by_name (dict(str, EnumValueDescriptor)): Dict mapping from 
    349        enum value name to :class:`EnumValueDescriptor` for that value. 
    350      extensions (list[FieldDescriptor]): All extensions defined directly within 
    351        this message type (NOT within a nested type). 
    352      extensions_by_name (dict(str, FieldDescriptor)): Same FieldDescriptor 
    353        objects as :attr:`extensions`, but indexed by "name" attribute of each 
    354        FieldDescriptor. 
    355      is_extendable (bool):  Does this type define any extension ranges? 
    356      oneofs (list[OneofDescriptor]): The list of descriptors for oneof fields 
    357        in this message. 
    358      oneofs_by_name (dict(str, OneofDescriptor)): Same objects as in 
    359        :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.Descriptor 
    366 
    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-builtin 
    383        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 can 
    393  # fix right now since we don't know how many clients already rely on the 
    394  # 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-builtin 
    413      syntax=None, 
    414      is_map_entry=False, 
    415      create_key=None, 
    416  ): 
    417    """Arguments to __init__() are as described in the description 
    418 
    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 terse 
    443    #      syntax: for f in descriptor.fields: ... 
    444    self.fields = fields 
    445    for field in self.fields: 
    446      field.containing_type = self 
    447      field.file = file 
    448    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 = None 
    451 
    452    self.nested_types = nested_types 
    453    for nested_type in nested_types: 
    454      nested_type.containing_type = self 
    455    self.nested_types_by_name = dict((t.name, t) for t in nested_types) 
    456 
    457    self.enum_types = enum_types 
    458    for enum_type in self.enum_types: 
    459      enum_type.containing_type = self 
    460    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.values 
    463    ) 
    464 
    465    self.extensions = extensions 
    466    for extension in self.extensions: 
    467      extension.extension_scope = self 
    468    self.extensions_by_name = dict((f.name, f) for f in extensions) 
    469    self.is_extendable = is_extendable 
    470    self.extension_ranges = extension_ranges 
    471    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 = self 
    475      oneof.file = file 
    476    self._is_map_entry = is_map_entry 
    477 
    478  @property 
    479  def _parent(self): 
    480    return self.containing_type or self.file 
    481 
    482  @property 
    483  def fields_by_camelcase_name(self): 
    484    """Same FieldDescriptor objects as in :attr:`fields`, but indexed by 
    485 
    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.fields 
    491      ) 
    492    return self._fields_by_camelcase_name 
    493 
    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 valid 
    508        value for the enum. 
    509    """ 
    510    return self.enum_types_by_name[enum].values_by_number[value].name 
    511 
    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 allowed 
    525#     to specify a default value. 
    526#   * [Other examples here as needed]. 
    527# 
    528# TODO: for this and other *Descriptor classes, we 
    529# might also want to lock things down aggressively (e.g., 
    530# prevent clients from setting the attributes).  Having 
    531# stronger invariants here in general will reduce the number 
    532# 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 is 
    539      particularly relevant for extensions. 
    540    index (int): Dense, 0-indexed index giving the order that this field 
    541      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 to 
    545      represent this field. 
    546    label (int): (One of the LABEL_* constants below) Tells whether this field 
    547      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 for 
    551      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 that 
    554      contains this field.  Set by the Descriptor constructor if we're passed 
    555      into one. Somewhat confusingly, for extension fields, this is the 
    556      descriptor of the EXTENDED message, not the descriptor of the message 
    557      containing this field.  (See is_extension and extension_scope below). 
    558    message_type (Descriptor): If a composite field, a descriptor of the message 
    559      type contained in this field.  Otherwise, this is None. 
    560    enum_type (EnumDescriptor): If this field contains an enum, a descriptor of 
    561      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. Gives 
    564      the message that immediately contains this extension field. Will be None 
    565      iff we're a top-level (file-level) extension field. 
    566    options (descriptor_pb2.FieldOptions): Protocol message field options or 
    567      None to use default field options. 
    568    containing_oneof (OneofDescriptor): If the field is a member of a oneof 
    569      union, contains its descriptor. Otherwise, None. 
    570    file (FileDescriptor): Reference to file descriptor. 
    571  """ 
    572 
    573  # Must be consistent with C++ FieldDescriptor::Type enum in 
    574  # descriptor.h. 
    575  # 
    576  # TODO: Find a way to eliminate this repetition. 
    577  TYPE_DOUBLE = 1 
    578  TYPE_FLOAT = 2 
    579  TYPE_INT64 = 3 
    580  TYPE_UINT64 = 4 
    581  TYPE_INT32 = 5 
    582  TYPE_FIXED64 = 6 
    583  TYPE_FIXED32 = 7 
    584  TYPE_BOOL = 8 
    585  TYPE_STRING = 9 
    586  TYPE_GROUP = 10 
    587  TYPE_MESSAGE = 11 
    588  TYPE_BYTES = 12 
    589  TYPE_UINT32 = 13 
    590  TYPE_ENUM = 14 
    591  TYPE_SFIXED32 = 15 
    592  TYPE_SFIXED64 = 16 
    593  TYPE_SINT32 = 17 
    594  TYPE_SINT64 = 18 
    595  MAX_TYPE = 18 
    596 
    597  # Must be consistent with C++ FieldDescriptor::CppType enum in 
    598  # descriptor.h. 
    599  # 
    600  # TODO: Find a way to eliminate this repetition. 
    601  CPPTYPE_INT32 = 1 
    602  CPPTYPE_INT64 = 2 
    603  CPPTYPE_UINT32 = 3 
    604  CPPTYPE_UINT64 = 4 
    605  CPPTYPE_DOUBLE = 5 
    606  CPPTYPE_FLOAT = 6 
    607  CPPTYPE_BOOL = 7 
    608  CPPTYPE_ENUM = 8 
    609  CPPTYPE_STRING = 9 
    610  CPPTYPE_MESSAGE = 10 
    611  MAX_CPPTYPE = 10 
    612 
    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 in 
    635  # descriptor.h. 
    636  # 
    637  # TODO: Find a way to eliminate this repetition. 
    638  LABEL_OPTIONAL = 1 
    639  LABEL_REQUIRED = 2 
    640  LABEL_REPEATED = 3 
    641  MAX_LABEL = 3 
    642 
    643  # Must be consistent with C++ constants kMaxNumber, kFirstReservedNumber, 
    644  # and kLastReservedNumber in descriptor.h 
    645  MAX_FIELD_NUMBER = (1 << 29) - 1 
    646  FIRST_RESERVED_FIELD_NUMBER = 19000 
    647  LAST_RESERVED_FIELD_NUMBER = 19999 
    648 
    649  if _USE_C_DESCRIPTORS: 
    650    _C_DESCRIPTOR_CLASS = _message.FieldDescriptor 
    651 
    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-builtin 
    675      _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-builtin 
    704    """The arguments are as described in the description of FieldDescriptor 
    705 
    706    attributes above. 
    707 
    708    Note that containing_type may be None, and may be set later if necessary 
    709    (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 = name 
    719    self.full_name = full_name 
    720    self._camelcase_name = None 
    721    if json_name is None: 
    722      self.json_name = _ToJsonName(name) 
    723    else: 
    724      self.json_name = json_name 
    725    self.index = index 
    726    self.number = number 
    727    self._type = type 
    728    self.cpp_type = cpp_type 
    729    self._label = label 
    730    self.has_default_value = has_default_value 
    731    self.default_value = default_value 
    732    self.containing_type = containing_type 
    733    self.message_type = message_type 
    734    self.enum_type = enum_type 
    735    self.is_extension = is_extension 
    736    self.extension_scope = extension_scope 
    737    self.containing_oneof = containing_oneof 
    738    if api_implementation.Type() == 'python': 
    739      self._cdescriptor = None 
    740    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  @property 
    747  def _parent(self): 
    748    if self.containing_oneof: 
    749      return self.containing_oneof 
    750    if self.is_extension: 
    751      return self.extension_scope or self.file 
    752    return self.containing_type 
    753 
    754  def _InferLegacyFeatures(self, edition, options, features): 
    755    # pylint: disable=g-import-not-at-top 
    756    from google.protobuf import descriptor_pb2 
    757 
    758    if edition >= descriptor_pb2.Edition.EDITION_2023: 
    759      return 
    760 
    761    if self._label == FieldDescriptor.LABEL_REQUIRED: 
    762      features.field_presence = ( 
    763          descriptor_pb2.FeatureSet.FieldPresence.LEGACY_REQUIRED 
    764      ) 
    765 
    766    if self._type == FieldDescriptor.TYPE_GROUP: 
    767      features.message_encoding = ( 
    768          descriptor_pb2.FeatureSet.MessageEncoding.DELIMITED 
    769      ) 
    770 
    771    if options.HasField('packed'): 
    772      features.repeated_field_encoding = ( 
    773          descriptor_pb2.FeatureSet.RepeatedFieldEncoding.PACKED 
    774          if options.packed 
    775          else descriptor_pb2.FeatureSet.RepeatedFieldEncoding.EXPANDED 
    776      ) 
    777 
    778  @property 
    779  def type(self): 
    780    if ( 
    781        self._GetFeatures().message_encoding 
    782        == _FEATURESET_MESSAGE_ENCODING_DELIMITED 
    783        and self.message_type 
    784        and not self.message_type.GetOptions().map_entry 
    785        and not self.containing_type.GetOptions().map_entry 
    786    ): 
    787      return FieldDescriptor.TYPE_GROUP 
    788    return self._type 
    789 
    790  @type.setter 
    791  def type(self, val): 
    792    self._type = val 
    793 
    794  @property 
    795  def label(self): 
    796    _Deprecated('label property', 'is_required or is_repeated properties') 
    797 
    798    if ( 
    799        self._GetFeatures().field_presence 
    800        == _FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED 
    801    ): 
    802      return FieldDescriptor.LABEL_REQUIRED 
    803    return self._label 
    804 
    805  @property 
    806  def is_required(self): 
    807    """Returns if the field is required.""" 
    808    return ( 
    809        self._GetFeatures().field_presence 
    810        == _FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED 
    811    ) 
    812 
    813  @property 
    814  def is_repeated(self): 
    815    """Returns if the field is repeated.""" 
    816    return self._label == FieldDescriptor.LABEL_REPEATED 
    817 
    818  @property 
    819  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_name 
    828 
    829  @property 
    830  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 False 
    838    if ( 
    839        self.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE 
    840        or self.is_extension 
    841        or self.containing_oneof 
    842    ): 
    843      return True 
    844 
    845    return ( 
    846        self._GetFeatures().field_presence 
    847        != _FEATURESET_FIELD_PRESENCE_IMPLICIT 
    848    ) 
    849 
    850  @property 
    851  def is_packed(self): 
    852    """Returns if the field is packed.""" 
    853    if not self.is_repeated: 
    854      return False 
    855    field_type = self.type 
    856    if ( 
    857        field_type == FieldDescriptor.TYPE_STRING 
    858        or field_type == FieldDescriptor.TYPE_GROUP 
    859        or field_type == FieldDescriptor.TYPE_MESSAGE 
    860        or field_type == FieldDescriptor.TYPE_BYTES 
    861    ): 
    862      return False 
    863 
    864    return ( 
    865        self._GetFeatures().repeated_field_encoding 
    866        == _FEATURESET_REPEATED_FIELD_ENCODING_PACKED 
    867    ) 
    868 
    869  @staticmethod 
    870  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 the 
    874    'C++' datatype - and they're not the same. This helper method should 
    875    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 any 
    897      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`, but 
    900      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 of 
    904      this enum, or None if this is an enum defined at the top level in a .proto 
    905      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 use 
    908      default enum options. 
    909  """ 
    910 
    911  if _USE_C_DESCRIPTORS: 
    912    _C_DESCRIPTOR_CLASS = _message.EnumDescriptor 
    913 
    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-builtin 
    924        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-builtin 
    941      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 = values 
    966    for value in self.values: 
    967      value.file = file 
    968      value.type = self 
    969    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  @property 
    974  def _parent(self): 
    975    return self.containing_type or self.file 
    976 
    977  @property 
    978  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 unknown 
    984      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 are 
    988    treated as closed when used as the type of fields defined in a 
    989    `syntax = proto2;` file. This quirk is not present in all runtimes; as of 
    990    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 target 
    997    runtime's enum handling quirks. 
    998    """ 
    999    return self._GetFeatures().enum_type == _FEATURESET_ENUM_TYPE_CLOSED 
    1000 
    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 appears 
    1017      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 or 
    1022      None to use default enum value options options. 
    1023  """ 
    1024 
    1025  if _USE_C_DESCRIPTORS: 
    1026    _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor 
    1027 
    1028    def __new__( 
    1029        cls, 
    1030        name, 
    1031        index, 
    1032        number, 
    1033        type=None,  # pylint: disable=redefined-builtin 
    1034        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 the 
    1040      # 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 None 
    1044 
    1045  def __init__( 
    1046      self, 
    1047      name, 
    1048      index, 
    1049      number, 
    1050      type=None,  # pylint: disable=redefined-builtin 
    1051      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 = name 
    1066    self.index = index 
    1067    self.number = number 
    1068    self.type = type 
    1069 
    1070  @property 
    1071  def _parent(self): 
    1072    return self.type 
    1073 
    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 its 
    1082      containing type. 
    1083    containing_type (Descriptor): :class:`Descriptor` of the protocol message 
    1084      type that contains this field.  Set by the :class:`Descriptor` constructor 
    1085      if we're passed into one. 
    1086    fields (list[FieldDescriptor]): The list of field descriptors this oneof can 
    1087      contain. 
    1088  """ 
    1089 
    1090  if _USE_C_DESCRIPTORS: 
    1091    _C_DESCRIPTOR_CLASS = _message.OneofDescriptor 
    1092 
    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 = name 
    1129    self.full_name = full_name 
    1130    self.index = index 
    1131    self.containing_type = containing_type 
    1132    self.fields = fields 
    1133 
    1134  @property 
    1135  def _parent(self): 
    1136    return self.containing_type 
    1137 
    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 definition 
    1146      appears within the .proto file. 
    1147    methods (list[MethodDescriptor]): List of methods provided by this service. 
    1148    methods_by_name (dict(str, MethodDescriptor)): Same 
    1149      :class:`MethodDescriptor` objects as in :attr:`methods_by_name`, but 
    1150      indexed by "name" attribute in each :class:`MethodDescriptor`. 
    1151    options (descriptor_pb2.ServiceOptions): Service options message or None to 
    1152      use default service options. 
    1153    file (FileDescriptor): Reference to file info. 
    1154  """ 
    1155 
    1156  if _USE_C_DESCRIPTORS: 
    1157    _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor 
    1158 
    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-builtin 
    1168        serialized_start=None, 
    1169        serialized_end=None, 
    1170        create_key=None, 
    1171    ): 
    1172      _message.Message._CheckCalledFromGeneratedFile()  # pylint: disable=protected-access 
    1173      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-builtin 
    1184      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, 
    1201    ) 
    1202    self.index = index 
    1203    self.methods = methods 
    1204    self.methods_by_name = dict((m.name, m) for m in methods) 
    1205    # Set the containing service for each method in this service. 
    1206    for method in self.methods: 
    1207      method.file = self.file 
    1208      method.containing_service = self 
    1209 
    1210  @property 
    1211  def _parent(self): 
    1212    return self.file 
    1213 
    1214  def FindMethodByName(self, name): 
    1215    """Searches for the specified method, and returns its descriptor. 
    1216 
    1217    Args: 
    1218      name (str): Name of the method. 
    1219 
    1220    Returns: 
    1221      MethodDescriptor: The descriptor for the requested method. 
    1222 
    1223    Raises: 
    1224      KeyError: if the method cannot be found in the service. 
    1225    """ 
    1226    return self.methods_by_name[name] 
    1227 
    1228  def CopyToProto(self, proto): 
    1229    """Copies this to a descriptor_pb2.ServiceDescriptorProto. 
    1230 
    1231    Args: 
    1232      proto (descriptor_pb2.ServiceDescriptorProto): An empty descriptor proto. 
    1233    """ 
    1234    # This function is overridden to give a better doc comment. 
    1235    super(ServiceDescriptor, self).CopyToProto(proto) 
    1236 
    1237 
    1238class MethodDescriptor(DescriptorBase): 
    1239  """Descriptor for a method in a service. 
    1240 
    1241  Attributes: 
    1242    name (str): Name of the method within the service. 
    1243    full_name (str): Full name of method. 
    1244    index (int): 0-indexed index of the method inside the service. 
    1245    containing_service (ServiceDescriptor): The service that contains this 
    1246      method. 
    1247    input_type (Descriptor): The descriptor of the message that this method 
    1248      accepts. 
    1249    output_type (Descriptor): The descriptor of the message that this method 
    1250      returns. 
    1251    client_streaming (bool): Whether this method uses client streaming. 
    1252    server_streaming (bool): Whether this method uses server streaming. 
    1253    options (descriptor_pb2.MethodOptions or None): Method options message, or 
    1254      None to use default method options. 
    1255  """ 
    1256 
    1257  if _USE_C_DESCRIPTORS: 
    1258    _C_DESCRIPTOR_CLASS = _message.MethodDescriptor 
    1259 
    1260    def __new__( 
    1261        cls, 
    1262        name, 
    1263        full_name, 
    1264        index, 
    1265        containing_service, 
    1266        input_type, 
    1267        output_type, 
    1268        client_streaming=False, 
    1269        server_streaming=False, 
    1270        options=None, 
    1271        serialized_options=None, 
    1272        create_key=None, 
    1273    ): 
    1274      _message.Message._CheckCalledFromGeneratedFile()  # pylint: disable=protected-access 
    1275      return _message.default_pool.FindMethodByName(full_name) 
    1276 
    1277  def __init__( 
    1278      self, 
    1279      name, 
    1280      full_name, 
    1281      index, 
    1282      containing_service, 
    1283      input_type, 
    1284      output_type, 
    1285      client_streaming=False, 
    1286      server_streaming=False, 
    1287      options=None, 
    1288      serialized_options=None, 
    1289      create_key=None, 
    1290  ): 
    1291    """The arguments are as described in the description of MethodDescriptor 
    1292 
    1293    attributes above. 
    1294 
    1295    Note that containing_service may be None, and may be set later if necessary. 
    1296    """ 
    1297    if create_key is not _internal_create_key: 
    1298      _Deprecated('create function MethodDescriptor()') 
    1299 
    1300    super(MethodDescriptor, self).__init__( 
    1301        containing_service.file if containing_service else None, 
    1302        options, 
    1303        serialized_options, 
    1304        'MethodOptions', 
    1305    ) 
    1306    self.name = name 
    1307    self.full_name = full_name 
    1308    self.index = index 
    1309    self.containing_service = containing_service 
    1310    self.input_type = input_type 
    1311    self.output_type = output_type 
    1312    self.client_streaming = client_streaming 
    1313    self.server_streaming = server_streaming 
    1314 
    1315  @property 
    1316  def _parent(self): 
    1317    return self.containing_service 
    1318 
    1319  def CopyToProto(self, proto): 
    1320    """Copies this to a descriptor_pb2.MethodDescriptorProto. 
    1321 
    1322    Args: 
    1323      proto (descriptor_pb2.MethodDescriptorProto): An empty descriptor proto. 
    1324 
    1325    Raises: 
    1326      Error: If self couldn't be serialized, due to too few constructor 
    1327        arguments. 
    1328    """ 
    1329    if self.containing_service is not None: 
    1330      from google.protobuf import descriptor_pb2 
    1331 
    1332      service_proto = descriptor_pb2.ServiceDescriptorProto() 
    1333      self.containing_service.CopyToProto(service_proto) 
    1334      proto.CopyFrom(service_proto.method[self.index]) 
    1335    else: 
    1336      raise Error('Descriptor does not contain a service.') 
    1337 
    1338 
    1339class FileDescriptor(DescriptorBase): 
    1340  """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto. 
    1341 
    1342  Note that :attr:`enum_types_by_name`, :attr:`extensions_by_name`, and 
    1343  :attr:`dependencies` fields are only set by the 
    1344  :py:mod:`google.protobuf.message_factory` module, and not by the generated 
    1345  proto code. 
    1346 
    1347  Attributes: 
    1348    name (str): Name of file, relative to root of source tree. 
    1349    package (str): Name of the package 
    1350    edition (Edition): Enum value indicating edition of the file 
    1351    serialized_pb (bytes): Byte string of serialized 
    1352      :class:`descriptor_pb2.FileDescriptorProto`. 
    1353    dependencies (list[FileDescriptor]): List of other :class:`FileDescriptor` 
    1354      objects this :class:`FileDescriptor` depends on. 
    1355    public_dependencies (list[FileDescriptor]): A subset of 
    1356      :attr:`dependencies`, which were declared as "public". 
    1357    message_types_by_name (dict(str, Descriptor)): Mapping from message names to 
    1358      their :class:`Descriptor`. 
    1359    enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to 
    1360      their :class:`EnumDescriptor`. 
    1361    extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension 
    1362      names declared at file scope to their :class:`FieldDescriptor`. 
    1363    services_by_name (dict(str, ServiceDescriptor)): Mapping from services' 
    1364      names to their :class:`ServiceDescriptor`. 
    1365    pool (DescriptorPool): The pool this descriptor belongs to.  When not passed 
    1366      to the constructor, the global default pool is used. 
    1367  """ 
    1368 
    1369  if _USE_C_DESCRIPTORS: 
    1370    _C_DESCRIPTOR_CLASS = _message.FileDescriptor 
    1371 
    1372    def __new__( 
    1373        cls, 
    1374        name, 
    1375        package, 
    1376        options=None, 
    1377        serialized_options=None, 
    1378        serialized_pb=None, 
    1379        dependencies=None, 
    1380        public_dependencies=None, 
    1381        syntax=None, 
    1382        edition=None, 
    1383        pool=None, 
    1384        create_key=None, 
    1385    ): 
    1386      # FileDescriptor() is called from various places, not only from generated 
    1387      # files, to register dynamic proto files and messages. 
    1388      # pylint: disable=g-explicit-bool-comparison 
    1389      if serialized_pb: 
    1390        return _message.default_pool.AddSerializedFile(serialized_pb) 
    1391      else: 
    1392        return super(FileDescriptor, cls).__new__(cls) 
    1393 
    1394  def __init__( 
    1395      self, 
    1396      name, 
    1397      package, 
    1398      options=None, 
    1399      serialized_options=None, 
    1400      serialized_pb=None, 
    1401      dependencies=None, 
    1402      public_dependencies=None, 
    1403      syntax=None, 
    1404      edition=None, 
    1405      pool=None, 
    1406      create_key=None, 
    1407  ): 
    1408    """Constructor.""" 
    1409    if create_key is not _internal_create_key: 
    1410      _Deprecated('create function FileDescriptor()') 
    1411 
    1412    super(FileDescriptor, self).__init__( 
    1413        self, options, serialized_options, 'FileOptions' 
    1414    ) 
    1415 
    1416    if edition and edition != 'EDITION_UNKNOWN': 
    1417      self._edition = edition 
    1418    elif syntax == 'proto3': 
    1419      self._edition = 'EDITION_PROTO3' 
    1420    else: 
    1421      self._edition = 'EDITION_PROTO2' 
    1422 
    1423    if pool is None: 
    1424      from google.protobuf import descriptor_pool 
    1425 
    1426      pool = descriptor_pool.Default() 
    1427    self.pool = pool 
    1428    self.message_types_by_name = {} 
    1429    self.name = name 
    1430    self.package = package 
    1431    self.serialized_pb = serialized_pb 
    1432 
    1433    self.enum_types_by_name = {} 
    1434    self.extensions_by_name = {} 
    1435    self.services_by_name = {} 
    1436    self.dependencies = dependencies or [] 
    1437    self.public_dependencies = public_dependencies or [] 
    1438 
    1439  def CopyToProto(self, proto): 
    1440    """Copies this to a descriptor_pb2.FileDescriptorProto. 
    1441 
    1442    Args: 
    1443      proto: An empty descriptor_pb2.FileDescriptorProto. 
    1444    """ 
    1445    proto.ParseFromString(self.serialized_pb) 
    1446 
    1447  @property 
    1448  def _parent(self): 
    1449    return None 
    1450 
    1451 
    1452def _ParseOptions(message, string): 
    1453  """Parses serialized options. 
    1454 
    1455  This helper function is used to parse serialized options in generated 
    1456  proto2 files. It must not be used outside proto2. 
    1457  """ 
    1458  message.ParseFromString(string) 
    1459  return message 
    1460 
    1461 
    1462def _ToCamelCase(name): 
    1463  """Converts name to camel-case and returns it.""" 
    1464  capitalize_next = False 
    1465  result = [] 
    1466 
    1467  for c in name: 
    1468    if c == '_': 
    1469      if result: 
    1470        capitalize_next = True 
    1471    elif capitalize_next: 
    1472      result.append(c.upper()) 
    1473      capitalize_next = False 
    1474    else: 
    1475      result += c 
    1476 
    1477  # Lower-case the first letter. 
    1478  if result and result[0].isupper(): 
    1479    result[0] = result[0].lower() 
    1480  return ''.join(result) 
    1481 
    1482 
    1483def _OptionsOrNone(descriptor_proto): 
    1484  """Returns the value of the field `options`, or None if it is not set.""" 
    1485  if descriptor_proto.HasField('options'): 
    1486    return descriptor_proto.options 
    1487  else: 
    1488    return None 
    1489 
    1490 
    1491def _ToJsonName(name): 
    1492  """Converts name to Json name and returns it.""" 
    1493  capitalize_next = False 
    1494  result = [] 
    1495 
    1496  for c in name: 
    1497    if c == '_': 
    1498      capitalize_next = True 
    1499    elif capitalize_next: 
    1500      result.append(c.upper()) 
    1501      capitalize_next = False 
    1502    else: 
    1503      result += c 
    1504 
    1505  return ''.join(result) 
    1506 
    1507 
    1508def MakeDescriptor( 
    1509    desc_proto, 
    1510    package='', 
    1511    build_file_if_cpp=True, 
    1512    syntax=None, 
    1513    edition=None, 
    1514    file_desc=None, 
    1515): 
    1516  """Make a protobuf Descriptor given a DescriptorProto protobuf. 
    1517 
    1518  Handles nested descriptors. Note that this is limited to the scope of defining 
    1519  a message inside of another message. Composite fields can currently only be 
    1520  resolved if the message is defined in the same scope as the field. 
    1521 
    1522  Args: 
    1523    desc_proto: The descriptor_pb2.DescriptorProto protobuf message. 
    1524    package: Optional package name for the new message Descriptor (string). 
    1525    build_file_if_cpp: Update the C++ descriptor pool if api matches. Set to 
    1526      False on recursion, so no duplicates are created. 
    1527    syntax: The syntax/semantics that should be used.  Set to "proto3" to get 
    1528      proto3 field presence semantics. 
    1529    edition: The edition that should be used if syntax is "edition". 
    1530    file_desc: A FileDescriptor to place this descriptor into. 
    1531 
    1532  Returns: 
    1533    A Descriptor for protobuf messages. 
    1534  """ 
    1535  # pylint: disable=g-import-not-at-top 
    1536  from google.protobuf import descriptor_pb2 
    1537 
    1538  # Generate a random name for this proto file to prevent conflicts with any 
    1539  # imported ones. We need to specify a file name so the descriptor pool 
    1540  # accepts our FileDescriptorProto, but it is not important what that file 
    1541  # name is actually set to. 
    1542  proto_name = binascii.hexlify(os.urandom(16)).decode('ascii') 
    1543 
    1544  if package: 
    1545    file_name = os.path.join(package.replace('.', '/'), proto_name + '.proto') 
    1546  else: 
    1547    file_name = proto_name + '.proto' 
    1548 
    1549  if api_implementation.Type() != 'python' and build_file_if_cpp: 
    1550    # The C++ implementation requires all descriptors to be backed by the same 
    1551    # definition in the C++ descriptor pool. To do this, we build a 
    1552    # FileDescriptorProto with the same definition as this descriptor and build 
    1553    # it into the pool. 
    1554    file_descriptor_proto = descriptor_pb2.FileDescriptorProto() 
    1555    file_descriptor_proto.message_type.add().MergeFrom(desc_proto) 
    1556 
    1557    if package: 
    1558      file_descriptor_proto.package = package 
    1559    file_descriptor_proto.name = file_name 
    1560 
    1561    _message.default_pool.Add(file_descriptor_proto) 
    1562    result = _message.default_pool.FindFileByName(file_descriptor_proto.name) 
    1563 
    1564    if _USE_C_DESCRIPTORS: 
    1565      return result.message_types_by_name[desc_proto.name] 
    1566 
    1567  if file_desc is None: 
    1568    file_desc = FileDescriptor( 
    1569        pool=None, 
    1570        name=file_name, 
    1571        package=package, 
    1572        syntax=syntax, 
    1573        edition=edition, 
    1574        options=None, 
    1575        serialized_pb='', 
    1576        dependencies=[], 
    1577        public_dependencies=[], 
    1578        create_key=_internal_create_key, 
    1579    ) 
    1580  full_message_name = [desc_proto.name] 
    1581  if package: 
    1582    full_message_name.insert(0, package) 
    1583 
    1584  # Create Descriptors for enum types 
    1585  enum_types = {} 
    1586  for enum_proto in desc_proto.enum_type: 
    1587    full_name = '.'.join(full_message_name + [enum_proto.name]) 
    1588    enum_desc = EnumDescriptor( 
    1589        enum_proto.name, 
    1590        full_name, 
    1591        None, 
    1592        [ 
    1593            EnumValueDescriptor( 
    1594                enum_val.name, 
    1595                ii, 
    1596                enum_val.number, 
    1597                create_key=_internal_create_key, 
    1598            ) 
    1599            for ii, enum_val in enumerate(enum_proto.value) 
    1600        ], 
    1601        file=file_desc, 
    1602        create_key=_internal_create_key, 
    1603    ) 
    1604    enum_types[full_name] = enum_desc 
    1605 
    1606  # Create Descriptors for nested types 
    1607  nested_types = {} 
    1608  for nested_proto in desc_proto.nested_type: 
    1609    full_name = '.'.join(full_message_name + [nested_proto.name]) 
    1610    # Nested types are just those defined inside of the message, not all types 
    1611    # used by fields in the message, so no loops are possible here. 
    1612    nested_desc = MakeDescriptor( 
    1613        nested_proto, 
    1614        package='.'.join(full_message_name), 
    1615        build_file_if_cpp=False, 
    1616        syntax=syntax, 
    1617        edition=edition, 
    1618        file_desc=file_desc, 
    1619    ) 
    1620    nested_types[full_name] = nested_desc 
    1621 
    1622  fields = [] 
    1623  for field_proto in desc_proto.field: 
    1624    full_name = '.'.join(full_message_name + [field_proto.name]) 
    1625    enum_desc = None 
    1626    nested_desc = None 
    1627    if field_proto.json_name: 
    1628      json_name = field_proto.json_name 
    1629    else: 
    1630      json_name = None 
    1631    if field_proto.HasField('type_name'): 
    1632      type_name = field_proto.type_name 
    1633      full_type_name = '.'.join( 
    1634          full_message_name + [type_name[type_name.rfind('.') + 1 :]] 
    1635      ) 
    1636      if full_type_name in nested_types: 
    1637        nested_desc = nested_types[full_type_name] 
    1638      elif full_type_name in enum_types: 
    1639        enum_desc = enum_types[full_type_name] 
    1640      # Else type_name references a non-local type, which isn't implemented 
    1641    field = FieldDescriptor( 
    1642        field_proto.name, 
    1643        full_name, 
    1644        field_proto.number - 1, 
    1645        field_proto.number, 
    1646        field_proto.type, 
    1647        FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), 
    1648        field_proto.label, 
    1649        None, 
    1650        nested_desc, 
    1651        enum_desc, 
    1652        None, 
    1653        False, 
    1654        None, 
    1655        options=_OptionsOrNone(field_proto), 
    1656        has_default_value=False, 
    1657        json_name=json_name, 
    1658        file=file_desc, 
    1659        create_key=_internal_create_key, 
    1660    ) 
    1661    fields.append(field) 
    1662 
    1663  desc_name = '.'.join(full_message_name) 
    1664  return Descriptor( 
    1665      desc_proto.name, 
    1666      desc_name, 
    1667      None, 
    1668      None, 
    1669      fields, 
    1670      list(nested_types.values()), 
    1671      list(enum_types.values()), 
    1672      [], 
    1673      options=_OptionsOrNone(desc_proto), 
    1674      file=file_desc, 
    1675      create_key=_internal_create_key, 
    1676  )