descriptor.py revision fbaaef999ba563838ebd00874ed8a1c01fbf286d
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# Protocol Buffers - Google's data interchange format
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# Copyright 2008 Google Inc.  All rights reserved.
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# http://code.google.com/p/protobuf/
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# Redistribution and use in source and binary forms, with or without
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# modification, are permitted provided that the following conditions are
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# met:
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#     * Redistributions of source code must retain the above copyright
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# notice, this list of conditions and the following disclaimer.
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#     * Redistributions in binary form must reproduce the above
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# copyright notice, this list of conditions and the following disclaimer
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# in the documentation and/or other materials provided with the
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# distribution.
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#     * Neither the name of Google Inc. nor the names of its
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# contributors may be used to endorse or promote products derived from
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# this software without specific prior written permission.
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
270b29a1fecc601de2f642ded891726ac3e460d74bElliott Hughes# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# TODO(robinson): We probably need to provide deep-copy methods for
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# descriptor types.  When a FieldDescriptor is passed into
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# Descriptor.__init__(), we should make a deep copy and then set
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# containing_type on it.  Alternatively, we could just get
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# rid of containing_type (iit's not needed for reflection.py, at least).
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# TODO(robinson): Print method?
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#
39f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson# TODO(robinson): Useful __repr__?
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
410b29a1fecc601de2f642ded891726ac3e460d74bElliott Hughes"""Descriptors essentially contain exactly the information found in a .proto
420b29a1fecc601de2f642ded891726ac3e460d74bElliott Hughesfile, in types that make this information accessible in Python.
430b29a1fecc601de2f642ded891726ac3e460d74bElliott Hughes"""
44f3afb1b6a4ace33bd60e5801bdb2fcb2e935d486Elliott Hughes
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project__author__ = 'robinson@google.com (Will Robinson)'
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectclass DescriptorBase(object):
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  """Descriptors base class.
50f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
51f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom  This class is the base of all descriptor classes. It provides common options
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  related functionaility.
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  """
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  def __init__(self, options, options_class_name):
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    """Initialize the descriptor given its options message and the name of the
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    class of the options message. The name of the class is required in case
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    the options message is None and has to be created.
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    """
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    self._options = options
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    self._options_class_name = options_class_name
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  def GetOptions(self):
64f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom    """Retrieves descriptor options.
65f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
66f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom    This method returns the options set or creates the default options for the
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    descriptor.
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    """
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    if self._options:
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      return self._options
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    from google.protobuf import descriptor_pb2
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    try:
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      options_class = getattr(descriptor_pb2, self._options_class_name)
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    except AttributeError:
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      raise RuntimeError('Unknown options class name %s!' %
763db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes                         (self._options_class_name))
773db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes    self._options = options_class()
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    return self._options
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
803db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectclass Descriptor(DescriptorBase):
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  """Descriptor for a protocol message type.
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
8558e5a8e6eeaf94d78522e0e9994c4565a3b33fdbJesse Wilson  A Descriptor instance has the following attributes:
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    name: (str) Name of this protocol message type.
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    full_name: (str) Fully-qualified name of this protocol message type,
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      which will include protocol "package" name and the name of any
90c6e0981e5a2d23a0758ed71a8086c4278a7832efJesse Wilson      enclosing types.
91f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
92c6e0981e5a2d23a0758ed71a8086c4278a7832efJesse Wilson    filename: (str) Name of the .proto file containing this message.
93c6e0981e5a2d23a0758ed71a8086c4278a7832efJesse Wilson
94c6e0981e5a2d23a0758ed71a8086c4278a7832efJesse Wilson    containing_type: (Descriptor) Reference to the descriptor of the
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      type containing us, or None if we have no containing type.
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    fields: (list of FieldDescriptors) Field descriptors for all
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      fields in this type.
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor
1003db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes      objects as in |fields|, but indexed by "number" attribute in each
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      FieldDescriptor.
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor
103e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom      objects as in |fields|, but indexed by "name" attribute in each
104e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom      FieldDescriptor.
105f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
106e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom    nested_types: (list of Descriptors) Descriptor references
107e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom      for all protocol message types nested within this one.
108e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom    nested_types_by_name: (dict str -> Descriptor) Same Descriptor
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      objects as in |nested_types|, but indexed by "name" attribute
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      in each Descriptor.
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1123db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes    enum_types: (list of EnumDescriptors) EnumDescriptor references
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      for all enums contained within this type.
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      objects as in |enum_types|, but indexed by "name" attribute
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      in each EnumDescriptor.
11758e5a8e6eeaf94d78522e0e9994c4565a3b33fdbJesse Wilson    enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      from enum value name to EnumValueDescriptor for that value.
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    extensions: (list of FieldDescriptor) All extensions defined directly
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      within this message type (NOT within a nested type).
1224401c75ac7d85da33472d0398d8166df6ce4beb5Elliott Hughes    extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      objects as |extensions|, but indexed by "name" attribute of each
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      FieldDescriptor.
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    options: (descriptor_pb2.MessageOptions) Protocol message options or None
1270b29a1fecc601de2f642ded891726ac3e460d74bElliott Hughes      to use default message options.
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  """
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  def __init__(self, name, full_name, filename, containing_type,
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project               fields, nested_types, enum_types, extensions, options=None):
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    """Arguments to __init__() are as described in the description
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    of Descriptor fields above.
1340b29a1fecc601de2f642ded891726ac3e460d74bElliott Hughes    """
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    super(Descriptor, self).__init__(options, 'MessageOptions')
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    self.name = name
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    self.full_name = full_name
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    self.filename = filename
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    self.containing_type = containing_type
1400b29a1fecc601de2f642ded891726ac3e460d74bElliott Hughes
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    # We have fields in addition to fields_by_name and fields_by_number,
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    # so that:
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    #   1. Clients can index fields by "order in which they're listed."
1440b29a1fecc601de2f642ded891726ac3e460d74bElliott Hughes    #   2. Clients can easily iterate over all fields with the terse
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    #      syntax: for f in descriptor.fields: ...
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    self.fields = fields
1470b29a1fecc601de2f642ded891726ac3e460d74bElliott Hughes    for field in self.fields:
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      field.containing_type = self
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    self.fields_by_number = dict((f.number, f) for f in fields)
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    self.fields_by_name = dict((f.name, f) for f in fields)
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    self.nested_types = nested_types
153753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes    self.nested_types_by_name = dict((t.name, t) for t in nested_types)
154753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes
155753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes    self.enum_types = enum_types
156753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes    for enum_type in self.enum_types:
1573db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes      enum_type.containing_type = self
158753dcd862b31e85766225590d90ba0b9f481176fElliott Hughes    self.enum_types_by_name = dict((t.name, t) for t in enum_types)
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    self.enum_values_by_name = dict(
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        (v.name, v) for t in enum_types for v in t.values)
16179ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes
1623db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes    self.extensions = extensions
1639f2b1b1c3bf9de560f29f257c855c7c85b405c0fElliott Hughes    for extension in self.extensions:
1649f2b1b1c3bf9de560f29f257c855c7c85b405c0fElliott Hughes      extension.extension_scope = self
1659f2b1b1c3bf9de560f29f257c855c7c85b405c0fElliott Hughes    self.extensions_by_name = dict((f.name, f) for f in extensions)
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# TODO(robinson): We should have aggressive checking here,
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project# for example:
17079ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes#   * If you specify a repeated field, you should not be allowed
17179ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes#     to specify a default value.
17279ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes#   * [Other examples here as needed].
17379ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes#
17479ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes# TODO(robinson): for this and other *Descriptor classes, we
17579ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes# might also want to lock things down aggressively (e.g.,
17679ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes# prevent clients from setting the attributes).  Having
17779ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes# stronger invariants here in general will reduce the number
17879ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes# of runtime checks we must do in reflection.py...
17979ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughesclass FieldDescriptor(DescriptorBase):
18079ff4e73fd689dae6667a8137ee57137962ff13aElliott Hughes
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  """Descriptor for a single field in a .proto file.
182221d0ccb4cc23ee0bf0646e9abe471fb48b3a1a8Elliott Hughes
183221d0ccb4cc23ee0bf0646e9abe471fb48b3a1a8Elliott Hughes  A FieldDescriptor instance has the following attriubtes:
184f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom
185f7aab022dcbfcd8f27b409ab92b4bca4a84d0b8aBrian Carlstrom    name: (str) Name of this field, exactly as it appears in .proto.
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    full_name: (str) Name of this field, including containing scope.  This is
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      particularly relevant for extensions.
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    index: (int) Dense, 0-indexed index giving the order that this
1893db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes      field textually appears within its message in the .proto file.
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    number: (int) Tag number declared for this field in the .proto file.
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    type: (One of the TYPE_* constants below) Declared type.
193fdd13e86ec613e46b68376f90d2c89c2ac33b4b5Elliott Hughes    cpp_type: (One of the CPPTYPE_* constants below) C++ type used to
194a9a57f2581773484d13e160fd3407692e825971aElliott Hughes      represent this field.
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    label: (One of the LABEL_* constants below) Tells whether this
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      field is optional, required, or repeated.
198fdd13e86ec613e46b68376f90d2c89c2ac33b4b5Elliott Hughes    default_value: (Varies) Default value of this field.  Only
1994d8e9333e494ceedff074def3b6e44f523f3830eElliott Hughes      meaningful for non-repeated scalar fields.  Repeated fields
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      should always set this to [], and non-repeated composite
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      fields should always set this to None.
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    containing_type: (Descriptor) Descriptor of the protocol message
2043db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes      type that contains this field.  Set by the Descriptor constructor
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      if we're passed into one.
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      Somewhat confusingly, for extension fields, this is the
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      descriptor of the EXTENDED message, not the descriptor
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      of the message containing this field.  (See is_extension and
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      extension_scope below).
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    message_type: (Descriptor) If a composite field, a descriptor
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      of the message type contained in this field.  Otherwise, this is None.
212b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    enum_type: (EnumDescriptor) If this field contains an enum, a
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      descriptor of that enum.  Otherwise, this is None.
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    is_extension: True iff this describes an extension field.
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    extension_scope: (Descriptor) Only meaningful if is_extension is True.
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      Gives the message that immediately contains this extension field.
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project      Will be None iff we're a top-level (file-level) extension field.
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    options: (descriptor_pb2.FieldOptions) Protocol message field options or
2213db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes      None to use default field options.
22258e5a8e6eeaf94d78522e0e9994c4565a3b33fdbJesse Wilson  """
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  # Must be consistent with C++ FieldDescriptor::Type enum in
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  # descriptor.h.
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  #
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  # TODO(robinson): Find a way to eliminate this repetition.
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_DOUBLE         = 1
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_FLOAT          = 2
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_INT64          = 3
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_UINT64         = 4
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_INT32          = 5
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_FIXED64        = 6
234f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes  TYPE_FIXED32        = 7
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_BOOL           = 8
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_STRING         = 9
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_GROUP          = 10
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_MESSAGE        = 11
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_BYTES          = 12
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_UINT32         = 13
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_ENUM           = 14
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project  TYPE_SFIXED32       = 15
243  TYPE_SFIXED64       = 16
244  TYPE_SINT32         = 17
245  TYPE_SINT64         = 18
246  MAX_TYPE            = 18
247
248  # Must be consistent with C++ FieldDescriptor::CppType enum in
249  # descriptor.h.
250  #
251  # TODO(robinson): Find a way to eliminate this repetition.
252  CPPTYPE_INT32       = 1
253  CPPTYPE_INT64       = 2
254  CPPTYPE_UINT32      = 3
255  CPPTYPE_UINT64      = 4
256  CPPTYPE_DOUBLE      = 5
257  CPPTYPE_FLOAT       = 6
258  CPPTYPE_BOOL        = 7
259  CPPTYPE_ENUM        = 8
260  CPPTYPE_STRING      = 9
261  CPPTYPE_MESSAGE     = 10
262  MAX_CPPTYPE         = 10
263
264  # Must be consistent with C++ FieldDescriptor::Label enum in
265  # descriptor.h.
266  #
267  # TODO(robinson): Find a way to eliminate this repetition.
268  LABEL_OPTIONAL      = 1
269  LABEL_REQUIRED      = 2
270  LABEL_REPEATED      = 3
271  MAX_LABEL           = 3
272
273  def __init__(self, name, full_name, index, number, type, cpp_type, label,
274               default_value, message_type, enum_type, containing_type,
275               is_extension, extension_scope, options=None):
276    """The arguments are as described in the description of FieldDescriptor
277    attributes above.
278
279    Note that containing_type may be None, and may be set later if necessary
280    (to deal with circular references between message types, for example).
281    Likewise for extension_scope.
282    """
283    super(FieldDescriptor, self).__init__(options, 'FieldOptions')
284    self.name = name
285    self.full_name = full_name
286    self.index = index
287    self.number = number
288    self.type = type
289    self.cpp_type = cpp_type
290    self.label = label
291    self.default_value = default_value
292    self.containing_type = containing_type
293    self.message_type = message_type
294    self.enum_type = enum_type
295    self.is_extension = is_extension
296    self.extension_scope = extension_scope
297
298
299class EnumDescriptor(DescriptorBase):
300
301  """Descriptor for an enum defined in a .proto file.
302
303  An EnumDescriptor instance has the following attributes:
304
305    name: (str) Name of the enum type.
306    full_name: (str) Full name of the type, including package name
307      and any enclosing type(s).
308    filename: (str) Name of the .proto file in which this appears.
309
310    values: (list of EnumValueDescriptors) List of the values
311      in this enum.
312    values_by_name: (dict str -> EnumValueDescriptor) Same as |values|,
313      but indexed by the "name" field of each EnumValueDescriptor.
314    values_by_number: (dict int -> EnumValueDescriptor) Same as |values|,
315      but indexed by the "number" field of each EnumValueDescriptor.
316    containing_type: (Descriptor) Descriptor of the immediate containing
317      type of this enum, or None if this is an enum defined at the
318      top level in a .proto file.  Set by Descriptor's constructor
319      if we're passed into one.
320    options: (descriptor_pb2.EnumOptions) Enum options message or
321      None to use default enum options.
322  """
323
324  def __init__(self, name, full_name, filename, values,
325               containing_type=None, options=None):
326    """Arguments are as described in the attribute description above."""
327    super(EnumDescriptor, self).__init__(options, 'EnumOptions')
328    self.name = name
329    self.full_name = full_name
330    self.filename = filename
331    self.values = values
332    for value in self.values:
333      value.type = self
334    self.values_by_name = dict((v.name, v) for v in values)
335    self.values_by_number = dict((v.number, v) for v in values)
336    self.containing_type = containing_type
337
338
339class EnumValueDescriptor(DescriptorBase):
340
341  """Descriptor for a single value within an enum.
342
343    name: (str) Name of this value.
344    index: (int) Dense, 0-indexed index giving the order that this
345      value appears textually within its enum in the .proto file.
346    number: (int) Actual number assigned to this enum value.
347    type: (EnumDescriptor) EnumDescriptor to which this value
348      belongs.  Set by EnumDescriptor's constructor if we're
349      passed into one.
350    options: (descriptor_pb2.EnumValueOptions) Enum value options message or
351      None to use default enum value options options.
352  """
353
354  def __init__(self, name, index, number, type=None, options=None):
355    """Arguments are as described in the attribute description above."""
356    super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions')
357    self.name = name
358    self.index = index
359    self.number = number
360    self.type = type
361
362
363class ServiceDescriptor(DescriptorBase):
364
365  """Descriptor for a service.
366
367    name: (str) Name of the service.
368    full_name: (str) Full name of the service, including package name.
369    index: (int) 0-indexed index giving the order that this services
370      definition appears withing the .proto file.
371    methods: (list of MethodDescriptor) List of methods provided by this
372      service.
373    options: (descriptor_pb2.ServiceOptions) Service options message or
374      None to use default service options.
375  """
376
377  def __init__(self, name, full_name, index, methods, options=None):
378    super(ServiceDescriptor, self).__init__(options, 'ServiceOptions')
379    self.name = name
380    self.full_name = full_name
381    self.index = index
382    self.methods = methods
383    # Set the containing service for each method in this service.
384    for method in self.methods:
385      method.containing_service = self
386
387  def FindMethodByName(self, name):
388    """Searches for the specified method, and returns its descriptor."""
389    for method in self.methods:
390      if name == method.name:
391        return method
392    return None
393
394
395class MethodDescriptor(DescriptorBase):
396
397  """Descriptor for a method in a service.
398
399  name: (str) Name of the method within the service.
400  full_name: (str) Full name of method.
401  index: (int) 0-indexed index of the method inside the service.
402  containing_service: (ServiceDescriptor) The service that contains this
403    method.
404  input_type: The descriptor of the message that this method accepts.
405  output_type: The descriptor of the message that this method returns.
406  options: (descriptor_pb2.MethodOptions) Method options message or
407    None to use default method options.
408  """
409
410  def __init__(self, name, full_name, index, containing_service,
411               input_type, output_type, options=None):
412    """The arguments are as described in the description of MethodDescriptor
413    attributes above.
414
415    Note that containing_service may be None, and may be set later if necessary.
416    """
417    super(MethodDescriptor, self).__init__(options, 'MethodOptions')
418    self.name = name
419    self.full_name = full_name
420    self.index = index
421    self.containing_service = containing_service
422    self.input_type = input_type
423    self.output_type = output_type
424
425
426def _ParseOptions(message, string):
427  """Parses serialized options.
428
429  This helper function is used to parse serialized options in generated
430  proto2 files. It must not be used outside proto2.
431  """
432  message.ParseFromString(string)
433  return message;
434