temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 1 | # Protocol Buffers - Google's data interchange format |
kenton@google.com | 24bf56f | 2008-09-24 20:31:01 +0000 | [diff] [blame] | 2 | # Copyright 2008 Google Inc. All rights reserved. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 3 | # http://code.google.com/p/protobuf/ |
| 4 | # |
kenton@google.com | 24bf56f | 2008-09-24 20:31:01 +0000 | [diff] [blame] | 5 | # Redistribution and use in source and binary forms, with or without |
| 6 | # modification, are permitted provided that the following conditions are |
| 7 | # met: |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 8 | # |
kenton@google.com | 24bf56f | 2008-09-24 20:31:01 +0000 | [diff] [blame] | 9 | # * Redistributions of source code must retain the above copyright |
| 10 | # notice, this list of conditions and the following disclaimer. |
| 11 | # * Redistributions in binary form must reproduce the above |
| 12 | # copyright notice, this list of conditions and the following disclaimer |
| 13 | # in the documentation and/or other materials provided with the |
| 14 | # distribution. |
| 15 | # * Neither the name of Google Inc. nor the names of its |
| 16 | # contributors may be used to endorse or promote products derived from |
| 17 | # this software without specific prior written permission. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 18 | # |
kenton@google.com | 24bf56f | 2008-09-24 20:31:01 +0000 | [diff] [blame] | 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 30 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 31 | """Descriptors essentially contain exactly the information found in a .proto |
| 32 | file, in types that make this information accessible in Python. |
| 33 | """ |
| 34 | |
| 35 | __author__ = 'robinson@google.com (Will Robinson)' |
| 36 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 37 | |
liujisi@google.com | 33165fe | 2010-11-02 13:14:58 +0000 | [diff] [blame^] | 38 | from google.protobuf.internal import api_implementation |
| 39 | |
| 40 | |
| 41 | if api_implementation.Type() == 'cpp': |
| 42 | from google.protobuf.internal import cpp_message |
| 43 | |
| 44 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 45 | class Error(Exception): |
| 46 | """Base error for this module.""" |
| 47 | |
| 48 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 49 | class DescriptorBase(object): |
| 50 | |
| 51 | """Descriptors base class. |
| 52 | |
| 53 | This class is the base of all descriptor classes. It provides common options |
| 54 | related functionaility. |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 55 | |
| 56 | Attributes: |
| 57 | has_options: True if the descriptor has non-default options. Usually it |
| 58 | is not necessary to read this -- just call GetOptions() which will |
| 59 | happily return the default instance. However, it's sometimes useful |
| 60 | for efficiency, and also useful inside the protobuf implementation to |
| 61 | avoid some bootstrapping issues. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 62 | """ |
| 63 | |
| 64 | def __init__(self, options, options_class_name): |
| 65 | """Initialize the descriptor given its options message and the name of the |
| 66 | class of the options message. The name of the class is required in case |
| 67 | the options message is None and has to be created. |
| 68 | """ |
| 69 | self._options = options |
| 70 | self._options_class_name = options_class_name |
| 71 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 72 | # Does this descriptor have non-default options? |
| 73 | self.has_options = options is not None |
| 74 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 75 | def GetOptions(self): |
| 76 | """Retrieves descriptor options. |
| 77 | |
| 78 | This method returns the options set or creates the default options for the |
| 79 | descriptor. |
| 80 | """ |
| 81 | if self._options: |
| 82 | return self._options |
| 83 | from google.protobuf import descriptor_pb2 |
| 84 | try: |
| 85 | options_class = getattr(descriptor_pb2, self._options_class_name) |
| 86 | except AttributeError: |
| 87 | raise RuntimeError('Unknown options class name %s!' % |
| 88 | (self._options_class_name)) |
| 89 | self._options = options_class() |
| 90 | return self._options |
| 91 | |
| 92 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 93 | class _NestedDescriptorBase(DescriptorBase): |
| 94 | """Common class for descriptors that can be nested.""" |
| 95 | |
| 96 | def __init__(self, options, options_class_name, name, full_name, |
| 97 | file, containing_type, serialized_start=None, |
| 98 | serialized_end=None): |
| 99 | """Constructor. |
| 100 | |
| 101 | Args: |
| 102 | options: Protocol message options or None |
| 103 | to use default message options. |
| 104 | options_class_name: (str) The class name of the above options. |
| 105 | |
| 106 | name: (str) Name of this protocol message type. |
| 107 | full_name: (str) Fully-qualified name of this protocol message type, |
| 108 | which will include protocol "package" name and the name of any |
| 109 | enclosing types. |
| 110 | file: (FileDescriptor) Reference to file info. |
| 111 | containing_type: if provided, this is a nested descriptor, with this |
| 112 | descriptor as parent, otherwise None. |
| 113 | serialized_start: The start index (inclusive) in block in the |
| 114 | file.serialized_pb that describes this descriptor. |
| 115 | serialized_end: The end index (exclusive) in block in the |
| 116 | file.serialized_pb that describes this descriptor. |
| 117 | """ |
| 118 | super(_NestedDescriptorBase, self).__init__( |
| 119 | options, options_class_name) |
| 120 | |
| 121 | self.name = name |
| 122 | # TODO(falk): Add function to calculate full_name instead of having it in |
| 123 | # memory? |
| 124 | self.full_name = full_name |
| 125 | self.file = file |
| 126 | self.containing_type = containing_type |
| 127 | |
| 128 | self._serialized_start = serialized_start |
| 129 | self._serialized_end = serialized_end |
| 130 | |
| 131 | def GetTopLevelContainingType(self): |
| 132 | """Returns the root if this is a nested type, or itself if its the root.""" |
| 133 | desc = self |
| 134 | while desc.containing_type is not None: |
| 135 | desc = desc.containing_type |
| 136 | return desc |
| 137 | |
| 138 | def CopyToProto(self, proto): |
| 139 | """Copies this to the matching proto in descriptor_pb2. |
| 140 | |
| 141 | Args: |
| 142 | proto: An empty proto instance from descriptor_pb2. |
| 143 | |
| 144 | Raises: |
| 145 | Error: If self couldnt be serialized, due to to few constructor arguments. |
| 146 | """ |
| 147 | if (self.file is not None and |
| 148 | self._serialized_start is not None and |
| 149 | self._serialized_end is not None): |
| 150 | proto.ParseFromString(self.file.serialized_pb[ |
| 151 | self._serialized_start:self._serialized_end]) |
| 152 | else: |
| 153 | raise Error('Descriptor does not contain serialization.') |
| 154 | |
| 155 | |
| 156 | class Descriptor(_NestedDescriptorBase): |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 157 | |
| 158 | """Descriptor for a protocol message type. |
| 159 | |
| 160 | A Descriptor instance has the following attributes: |
| 161 | |
| 162 | name: (str) Name of this protocol message type. |
| 163 | full_name: (str) Fully-qualified name of this protocol message type, |
| 164 | which will include protocol "package" name and the name of any |
| 165 | enclosing types. |
| 166 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 167 | containing_type: (Descriptor) Reference to the descriptor of the |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 168 | type containing us, or None if this is top-level. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 169 | |
| 170 | fields: (list of FieldDescriptors) Field descriptors for all |
| 171 | fields in this type. |
| 172 | fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor |
| 173 | objects as in |fields|, but indexed by "number" attribute in each |
| 174 | FieldDescriptor. |
| 175 | fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor |
| 176 | objects as in |fields|, but indexed by "name" attribute in each |
| 177 | FieldDescriptor. |
| 178 | |
| 179 | nested_types: (list of Descriptors) Descriptor references |
| 180 | for all protocol message types nested within this one. |
| 181 | nested_types_by_name: (dict str -> Descriptor) Same Descriptor |
| 182 | objects as in |nested_types|, but indexed by "name" attribute |
| 183 | in each Descriptor. |
| 184 | |
| 185 | enum_types: (list of EnumDescriptors) EnumDescriptor references |
| 186 | for all enums contained within this type. |
| 187 | enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor |
| 188 | objects as in |enum_types|, but indexed by "name" attribute |
| 189 | in each EnumDescriptor. |
| 190 | enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping |
| 191 | from enum value name to EnumValueDescriptor for that value. |
| 192 | |
| 193 | extensions: (list of FieldDescriptor) All extensions defined directly |
| 194 | within this message type (NOT within a nested type). |
| 195 | extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor |
| 196 | objects as |extensions|, but indexed by "name" attribute of each |
| 197 | FieldDescriptor. |
| 198 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 199 | is_extendable: Does this type define any extension ranges? |
| 200 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 201 | options: (descriptor_pb2.MessageOptions) Protocol message options or None |
| 202 | to use default message options. |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 203 | |
| 204 | file: (FileDescriptor) Reference to file descriptor. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 205 | """ |
| 206 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 207 | def __init__(self, name, full_name, filename, containing_type, fields, |
| 208 | nested_types, enum_types, extensions, options=None, |
| 209 | is_extendable=True, extension_ranges=None, file=None, |
| 210 | serialized_start=None, serialized_end=None): |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 211 | """Arguments to __init__() are as described in the description |
| 212 | of Descriptor fields above. |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 213 | |
| 214 | Note that filename is an obsolete argument, that is not used anymore. |
| 215 | Please use file.name to access this as an attribute. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 216 | """ |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 217 | super(Descriptor, self).__init__( |
| 218 | options, 'MessageOptions', name, full_name, file, |
| 219 | containing_type, serialized_start=serialized_start, |
| 220 | serialized_end=serialized_start) |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 221 | |
| 222 | # We have fields in addition to fields_by_name and fields_by_number, |
| 223 | # so that: |
| 224 | # 1. Clients can index fields by "order in which they're listed." |
| 225 | # 2. Clients can easily iterate over all fields with the terse |
| 226 | # syntax: for f in descriptor.fields: ... |
| 227 | self.fields = fields |
| 228 | for field in self.fields: |
| 229 | field.containing_type = self |
| 230 | self.fields_by_number = dict((f.number, f) for f in fields) |
| 231 | self.fields_by_name = dict((f.name, f) for f in fields) |
| 232 | |
| 233 | self.nested_types = nested_types |
| 234 | self.nested_types_by_name = dict((t.name, t) for t in nested_types) |
| 235 | |
| 236 | self.enum_types = enum_types |
| 237 | for enum_type in self.enum_types: |
| 238 | enum_type.containing_type = self |
| 239 | self.enum_types_by_name = dict((t.name, t) for t in enum_types) |
| 240 | self.enum_values_by_name = dict( |
| 241 | (v.name, v) for t in enum_types for v in t.values) |
| 242 | |
| 243 | self.extensions = extensions |
| 244 | for extension in self.extensions: |
| 245 | extension.extension_scope = self |
| 246 | self.extensions_by_name = dict((f.name, f) for f in extensions) |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 247 | self.is_extendable = is_extendable |
| 248 | self.extension_ranges = extension_ranges |
| 249 | |
| 250 | self._serialized_start = serialized_start |
| 251 | self._serialized_end = serialized_end |
| 252 | |
| 253 | def CopyToProto(self, proto): |
| 254 | """Copies this to a descriptor_pb2.DescriptorProto. |
| 255 | |
| 256 | Args: |
| 257 | proto: An empty descriptor_pb2.DescriptorProto. |
| 258 | """ |
| 259 | # This function is overriden to give a better doc comment. |
| 260 | super(Descriptor, self).CopyToProto(proto) |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 261 | |
| 262 | |
| 263 | # TODO(robinson): We should have aggressive checking here, |
| 264 | # for example: |
| 265 | # * If you specify a repeated field, you should not be allowed |
| 266 | # to specify a default value. |
| 267 | # * [Other examples here as needed]. |
| 268 | # |
| 269 | # TODO(robinson): for this and other *Descriptor classes, we |
| 270 | # might also want to lock things down aggressively (e.g., |
| 271 | # prevent clients from setting the attributes). Having |
| 272 | # stronger invariants here in general will reduce the number |
| 273 | # of runtime checks we must do in reflection.py... |
| 274 | class FieldDescriptor(DescriptorBase): |
| 275 | |
| 276 | """Descriptor for a single field in a .proto file. |
| 277 | |
| 278 | A FieldDescriptor instance has the following attriubtes: |
| 279 | |
| 280 | name: (str) Name of this field, exactly as it appears in .proto. |
| 281 | full_name: (str) Name of this field, including containing scope. This is |
| 282 | particularly relevant for extensions. |
| 283 | index: (int) Dense, 0-indexed index giving the order that this |
| 284 | field textually appears within its message in the .proto file. |
| 285 | number: (int) Tag number declared for this field in the .proto file. |
| 286 | |
| 287 | type: (One of the TYPE_* constants below) Declared type. |
| 288 | cpp_type: (One of the CPPTYPE_* constants below) C++ type used to |
| 289 | represent this field. |
| 290 | |
| 291 | label: (One of the LABEL_* constants below) Tells whether this |
| 292 | field is optional, required, or repeated. |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 293 | has_default_value: (bool) True if this field has a default value defined, |
| 294 | otherwise false. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 295 | default_value: (Varies) Default value of this field. Only |
| 296 | meaningful for non-repeated scalar fields. Repeated fields |
| 297 | should always set this to [], and non-repeated composite |
| 298 | fields should always set this to None. |
| 299 | |
| 300 | containing_type: (Descriptor) Descriptor of the protocol message |
| 301 | type that contains this field. Set by the Descriptor constructor |
| 302 | if we're passed into one. |
| 303 | Somewhat confusingly, for extension fields, this is the |
| 304 | descriptor of the EXTENDED message, not the descriptor |
| 305 | of the message containing this field. (See is_extension and |
| 306 | extension_scope below). |
| 307 | message_type: (Descriptor) If a composite field, a descriptor |
| 308 | of the message type contained in this field. Otherwise, this is None. |
| 309 | enum_type: (EnumDescriptor) If this field contains an enum, a |
| 310 | descriptor of that enum. Otherwise, this is None. |
| 311 | |
| 312 | is_extension: True iff this describes an extension field. |
| 313 | extension_scope: (Descriptor) Only meaningful if is_extension is True. |
| 314 | Gives the message that immediately contains this extension field. |
| 315 | Will be None iff we're a top-level (file-level) extension field. |
| 316 | |
| 317 | options: (descriptor_pb2.FieldOptions) Protocol message field options or |
| 318 | None to use default field options. |
| 319 | """ |
| 320 | |
| 321 | # Must be consistent with C++ FieldDescriptor::Type enum in |
| 322 | # descriptor.h. |
| 323 | # |
| 324 | # TODO(robinson): Find a way to eliminate this repetition. |
| 325 | TYPE_DOUBLE = 1 |
| 326 | TYPE_FLOAT = 2 |
| 327 | TYPE_INT64 = 3 |
| 328 | TYPE_UINT64 = 4 |
| 329 | TYPE_INT32 = 5 |
| 330 | TYPE_FIXED64 = 6 |
| 331 | TYPE_FIXED32 = 7 |
| 332 | TYPE_BOOL = 8 |
| 333 | TYPE_STRING = 9 |
| 334 | TYPE_GROUP = 10 |
| 335 | TYPE_MESSAGE = 11 |
| 336 | TYPE_BYTES = 12 |
| 337 | TYPE_UINT32 = 13 |
| 338 | TYPE_ENUM = 14 |
| 339 | TYPE_SFIXED32 = 15 |
| 340 | TYPE_SFIXED64 = 16 |
| 341 | TYPE_SINT32 = 17 |
| 342 | TYPE_SINT64 = 18 |
| 343 | MAX_TYPE = 18 |
| 344 | |
| 345 | # Must be consistent with C++ FieldDescriptor::CppType enum in |
| 346 | # descriptor.h. |
| 347 | # |
| 348 | # TODO(robinson): Find a way to eliminate this repetition. |
| 349 | CPPTYPE_INT32 = 1 |
| 350 | CPPTYPE_INT64 = 2 |
| 351 | CPPTYPE_UINT32 = 3 |
| 352 | CPPTYPE_UINT64 = 4 |
| 353 | CPPTYPE_DOUBLE = 5 |
| 354 | CPPTYPE_FLOAT = 6 |
| 355 | CPPTYPE_BOOL = 7 |
| 356 | CPPTYPE_ENUM = 8 |
| 357 | CPPTYPE_STRING = 9 |
| 358 | CPPTYPE_MESSAGE = 10 |
| 359 | MAX_CPPTYPE = 10 |
| 360 | |
| 361 | # Must be consistent with C++ FieldDescriptor::Label enum in |
| 362 | # descriptor.h. |
| 363 | # |
| 364 | # TODO(robinson): Find a way to eliminate this repetition. |
| 365 | LABEL_OPTIONAL = 1 |
| 366 | LABEL_REQUIRED = 2 |
| 367 | LABEL_REPEATED = 3 |
| 368 | MAX_LABEL = 3 |
| 369 | |
| 370 | def __init__(self, name, full_name, index, number, type, cpp_type, label, |
| 371 | default_value, message_type, enum_type, containing_type, |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 372 | is_extension, extension_scope, options=None, |
| 373 | has_default_value=True): |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 374 | """The arguments are as described in the description of FieldDescriptor |
| 375 | attributes above. |
| 376 | |
| 377 | Note that containing_type may be None, and may be set later if necessary |
| 378 | (to deal with circular references between message types, for example). |
| 379 | Likewise for extension_scope. |
| 380 | """ |
| 381 | super(FieldDescriptor, self).__init__(options, 'FieldOptions') |
| 382 | self.name = name |
| 383 | self.full_name = full_name |
| 384 | self.index = index |
| 385 | self.number = number |
| 386 | self.type = type |
| 387 | self.cpp_type = cpp_type |
| 388 | self.label = label |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 389 | self.has_default_value = has_default_value |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 390 | self.default_value = default_value |
| 391 | self.containing_type = containing_type |
| 392 | self.message_type = message_type |
| 393 | self.enum_type = enum_type |
| 394 | self.is_extension = is_extension |
| 395 | self.extension_scope = extension_scope |
liujisi@google.com | 33165fe | 2010-11-02 13:14:58 +0000 | [diff] [blame^] | 396 | if api_implementation.Type() == 'cpp': |
| 397 | if is_extension: |
| 398 | self._cdescriptor = cpp_message.GetExtensionDescriptor(full_name) |
| 399 | else: |
| 400 | self._cdescriptor = cpp_message.GetFieldDescriptor(full_name) |
| 401 | else: |
| 402 | self._cdescriptor = None |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 403 | |
| 404 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 405 | class EnumDescriptor(_NestedDescriptorBase): |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 406 | |
| 407 | """Descriptor for an enum defined in a .proto file. |
| 408 | |
| 409 | An EnumDescriptor instance has the following attributes: |
| 410 | |
| 411 | name: (str) Name of the enum type. |
| 412 | full_name: (str) Full name of the type, including package name |
| 413 | and any enclosing type(s). |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 414 | |
| 415 | values: (list of EnumValueDescriptors) List of the values |
| 416 | in this enum. |
| 417 | values_by_name: (dict str -> EnumValueDescriptor) Same as |values|, |
| 418 | but indexed by the "name" field of each EnumValueDescriptor. |
| 419 | values_by_number: (dict int -> EnumValueDescriptor) Same as |values|, |
| 420 | but indexed by the "number" field of each EnumValueDescriptor. |
| 421 | containing_type: (Descriptor) Descriptor of the immediate containing |
| 422 | type of this enum, or None if this is an enum defined at the |
| 423 | top level in a .proto file. Set by Descriptor's constructor |
| 424 | if we're passed into one. |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 425 | file: (FileDescriptor) Reference to file descriptor. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 426 | options: (descriptor_pb2.EnumOptions) Enum options message or |
| 427 | None to use default enum options. |
| 428 | """ |
| 429 | |
| 430 | def __init__(self, name, full_name, filename, values, |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 431 | containing_type=None, options=None, file=None, |
| 432 | serialized_start=None, serialized_end=None): |
| 433 | """Arguments are as described in the attribute description above. |
| 434 | |
| 435 | Note that filename is an obsolete argument, that is not used anymore. |
| 436 | Please use file.name to access this as an attribute. |
| 437 | """ |
| 438 | super(EnumDescriptor, self).__init__( |
| 439 | options, 'EnumOptions', name, full_name, file, |
| 440 | containing_type, serialized_start=serialized_start, |
| 441 | serialized_end=serialized_start) |
| 442 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 443 | self.values = values |
| 444 | for value in self.values: |
| 445 | value.type = self |
| 446 | self.values_by_name = dict((v.name, v) for v in values) |
| 447 | self.values_by_number = dict((v.number, v) for v in values) |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 448 | |
| 449 | self._serialized_start = serialized_start |
| 450 | self._serialized_end = serialized_end |
| 451 | |
| 452 | def CopyToProto(self, proto): |
| 453 | """Copies this to a descriptor_pb2.EnumDescriptorProto. |
| 454 | |
| 455 | Args: |
| 456 | proto: An empty descriptor_pb2.EnumDescriptorProto. |
| 457 | """ |
| 458 | # This function is overriden to give a better doc comment. |
| 459 | super(EnumDescriptor, self).CopyToProto(proto) |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 460 | |
| 461 | |
| 462 | class EnumValueDescriptor(DescriptorBase): |
| 463 | |
| 464 | """Descriptor for a single value within an enum. |
| 465 | |
| 466 | name: (str) Name of this value. |
| 467 | index: (int) Dense, 0-indexed index giving the order that this |
| 468 | value appears textually within its enum in the .proto file. |
| 469 | number: (int) Actual number assigned to this enum value. |
| 470 | type: (EnumDescriptor) EnumDescriptor to which this value |
| 471 | belongs. Set by EnumDescriptor's constructor if we're |
| 472 | passed into one. |
| 473 | options: (descriptor_pb2.EnumValueOptions) Enum value options message or |
| 474 | None to use default enum value options options. |
| 475 | """ |
| 476 | |
| 477 | def __init__(self, name, index, number, type=None, options=None): |
| 478 | """Arguments are as described in the attribute description above.""" |
| 479 | super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions') |
| 480 | self.name = name |
| 481 | self.index = index |
| 482 | self.number = number |
| 483 | self.type = type |
| 484 | |
| 485 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 486 | class ServiceDescriptor(_NestedDescriptorBase): |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 487 | |
| 488 | """Descriptor for a service. |
| 489 | |
| 490 | name: (str) Name of the service. |
| 491 | full_name: (str) Full name of the service, including package name. |
| 492 | index: (int) 0-indexed index giving the order that this services |
| 493 | definition appears withing the .proto file. |
| 494 | methods: (list of MethodDescriptor) List of methods provided by this |
| 495 | service. |
| 496 | options: (descriptor_pb2.ServiceOptions) Service options message or |
| 497 | None to use default service options. |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 498 | file: (FileDescriptor) Reference to file info. |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 499 | """ |
| 500 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 501 | def __init__(self, name, full_name, index, methods, options=None, file=None, |
| 502 | serialized_start=None, serialized_end=None): |
| 503 | super(ServiceDescriptor, self).__init__( |
| 504 | options, 'ServiceOptions', name, full_name, file, |
| 505 | None, serialized_start=serialized_start, |
| 506 | serialized_end=serialized_end) |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 507 | self.index = index |
| 508 | self.methods = methods |
| 509 | # Set the containing service for each method in this service. |
| 510 | for method in self.methods: |
| 511 | method.containing_service = self |
| 512 | |
| 513 | def FindMethodByName(self, name): |
| 514 | """Searches for the specified method, and returns its descriptor.""" |
| 515 | for method in self.methods: |
| 516 | if name == method.name: |
| 517 | return method |
| 518 | return None |
| 519 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 520 | def CopyToProto(self, proto): |
| 521 | """Copies this to a descriptor_pb2.ServiceDescriptorProto. |
| 522 | |
| 523 | Args: |
| 524 | proto: An empty descriptor_pb2.ServiceDescriptorProto. |
| 525 | """ |
| 526 | # This function is overriden to give a better doc comment. |
| 527 | super(ServiceDescriptor, self).CopyToProto(proto) |
| 528 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 529 | |
| 530 | class MethodDescriptor(DescriptorBase): |
| 531 | |
| 532 | """Descriptor for a method in a service. |
| 533 | |
| 534 | name: (str) Name of the method within the service. |
| 535 | full_name: (str) Full name of method. |
| 536 | index: (int) 0-indexed index of the method inside the service. |
| 537 | containing_service: (ServiceDescriptor) The service that contains this |
| 538 | method. |
| 539 | input_type: The descriptor of the message that this method accepts. |
| 540 | output_type: The descriptor of the message that this method returns. |
| 541 | options: (descriptor_pb2.MethodOptions) Method options message or |
| 542 | None to use default method options. |
| 543 | """ |
| 544 | |
| 545 | def __init__(self, name, full_name, index, containing_service, |
| 546 | input_type, output_type, options=None): |
| 547 | """The arguments are as described in the description of MethodDescriptor |
| 548 | attributes above. |
| 549 | |
| 550 | Note that containing_service may be None, and may be set later if necessary. |
| 551 | """ |
| 552 | super(MethodDescriptor, self).__init__(options, 'MethodOptions') |
| 553 | self.name = name |
| 554 | self.full_name = full_name |
| 555 | self.index = index |
| 556 | self.containing_service = containing_service |
| 557 | self.input_type = input_type |
| 558 | self.output_type = output_type |
| 559 | |
| 560 | |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 561 | class FileDescriptor(DescriptorBase): |
| 562 | """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto. |
| 563 | |
| 564 | name: name of file, relative to root of source tree. |
| 565 | package: name of the package |
| 566 | serialized_pb: (str) Byte string of serialized |
| 567 | descriptor_pb2.FileDescriptorProto. |
| 568 | """ |
| 569 | |
| 570 | def __init__(self, name, package, options=None, serialized_pb=None): |
| 571 | """Constructor.""" |
| 572 | super(FileDescriptor, self).__init__(options, 'FileOptions') |
| 573 | |
liujisi@google.com | 33165fe | 2010-11-02 13:14:58 +0000 | [diff] [blame^] | 574 | self.message_types_by_name = {} |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 575 | self.name = name |
| 576 | self.package = package |
| 577 | self.serialized_pb = serialized_pb |
liujisi@google.com | 33165fe | 2010-11-02 13:14:58 +0000 | [diff] [blame^] | 578 | if (api_implementation.Type() == 'cpp' and |
| 579 | self.serialized_pb is not None): |
| 580 | cpp_message.BuildFile(self.serialized_pb) |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 581 | |
| 582 | def CopyToProto(self, proto): |
| 583 | """Copies this to a descriptor_pb2.FileDescriptorProto. |
| 584 | |
| 585 | Args: |
| 586 | proto: An empty descriptor_pb2.FileDescriptorProto. |
| 587 | """ |
| 588 | proto.ParseFromString(self.serialized_pb) |
| 589 | |
| 590 | |
temporal | 40ee551 | 2008-07-10 02:12:20 +0000 | [diff] [blame] | 591 | def _ParseOptions(message, string): |
| 592 | """Parses serialized options. |
| 593 | |
| 594 | This helper function is used to parse serialized options in generated |
| 595 | proto2 files. It must not be used outside proto2. |
| 596 | """ |
| 597 | message.ParseFromString(string) |
kenton@google.com | fccb146 | 2009-12-18 02:11:36 +0000 | [diff] [blame] | 598 | return message |