diff options
Diffstat (limited to 'froofle/protobuf/descriptor.py')
| -rw-r--r-- | froofle/protobuf/descriptor.py | 433 |
1 files changed, 0 insertions, 433 deletions
diff --git a/froofle/protobuf/descriptor.py b/froofle/protobuf/descriptor.py deleted file mode 100644 index e74cf25e..00000000 --- a/froofle/protobuf/descriptor.py +++ /dev/null | |||
| @@ -1,433 +0,0 @@ | |||
| 1 | # Protocol Buffers - Google's data interchange format | ||
| 2 | # Copyright 2008 Google Inc. All rights reserved. | ||
| 3 | # http://code.google.com/p/protobuf/ | ||
| 4 | # | ||
| 5 | # Redistribution and use in source and binary forms, with or without | ||
| 6 | # modification, are permitted provided that the following conditions are | ||
| 7 | # met: | ||
| 8 | # | ||
| 9 | # * Redistributions of source code must retain the above copyright | ||
| 10 | # notice, this list of conditions and the following disclaimer. | ||
| 11 | # * Redistributions in binary form must reproduce the above | ||
| 12 | # copyright notice, this list of conditions and the following disclaimer | ||
| 13 | # in the documentation and/or other materials provided with the | ||
| 14 | # distribution. | ||
| 15 | # * Neither the name of Google Inc. nor the names of its | ||
| 16 | # contributors may be used to endorse or promote products derived from | ||
| 17 | # this software without specific prior written permission. | ||
| 18 | # | ||
| 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 20 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 21 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 22 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 23 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 24 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 25 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 26 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 27 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 28 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | |||
| 31 | # TODO(robinson): We probably need to provide deep-copy methods for | ||
| 32 | # descriptor types. When a FieldDescriptor is passed into | ||
| 33 | # Descriptor.__init__(), we should make a deep copy and then set | ||
| 34 | # containing_type on it. Alternatively, we could just get | ||
| 35 | # rid of containing_type (iit's not needed for reflection.py, at least). | ||
| 36 | # | ||
| 37 | # TODO(robinson): Print method? | ||
| 38 | # | ||
| 39 | # TODO(robinson): Useful __repr__? | ||
| 40 | |||
| 41 | """Descriptors essentially contain exactly the information found in a .proto | ||
| 42 | file, in types that make this information accessible in Python. | ||
| 43 | """ | ||
| 44 | |||
| 45 | __author__ = 'robinson@google.com (Will Robinson)' | ||
| 46 | |||
| 47 | class DescriptorBase(object): | ||
| 48 | |||
| 49 | """Descriptors base class. | ||
| 50 | |||
| 51 | This class is the base of all descriptor classes. It provides common options | ||
| 52 | related functionaility. | ||
| 53 | """ | ||
| 54 | |||
| 55 | def __init__(self, options, options_class_name): | ||
| 56 | """Initialize the descriptor given its options message and the name of the | ||
| 57 | class of the options message. The name of the class is required in case | ||
| 58 | the options message is None and has to be created. | ||
| 59 | """ | ||
| 60 | self._options = options | ||
| 61 | self._options_class_name = options_class_name | ||
| 62 | |||
| 63 | def GetOptions(self): | ||
| 64 | """Retrieves descriptor options. | ||
| 65 | |||
| 66 | This method returns the options set or creates the default options for the | ||
| 67 | descriptor. | ||
| 68 | """ | ||
| 69 | if self._options: | ||
| 70 | return self._options | ||
| 71 | from froofle.protobuf import descriptor_pb2 | ||
| 72 | try: | ||
| 73 | options_class = getattr(descriptor_pb2, self._options_class_name) | ||
| 74 | except AttributeError: | ||
| 75 | raise RuntimeError('Unknown options class name %s!' % | ||
| 76 | (self._options_class_name)) | ||
| 77 | self._options = options_class() | ||
| 78 | return self._options | ||
| 79 | |||
| 80 | |||
| 81 | class Descriptor(DescriptorBase): | ||
| 82 | |||
| 83 | """Descriptor for a protocol message type. | ||
| 84 | |||
| 85 | A Descriptor instance has the following attributes: | ||
| 86 | |||
| 87 | name: (str) Name of this protocol message type. | ||
| 88 | full_name: (str) Fully-qualified name of this protocol message type, | ||
| 89 | which will include protocol "package" name and the name of any | ||
| 90 | enclosing types. | ||
| 91 | |||
| 92 | filename: (str) Name of the .proto file containing this message. | ||
| 93 | |||
| 94 | containing_type: (Descriptor) Reference to the descriptor of the | ||
| 95 | type containing us, or None if we have no containing type. | ||
| 96 | |||
| 97 | fields: (list of FieldDescriptors) Field descriptors for all | ||
| 98 | fields in this type. | ||
| 99 | fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor | ||
| 100 | objects as in |fields|, but indexed by "number" attribute in each | ||
| 101 | FieldDescriptor. | ||
| 102 | fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor | ||
| 103 | objects as in |fields|, but indexed by "name" attribute in each | ||
| 104 | FieldDescriptor. | ||
| 105 | |||
| 106 | nested_types: (list of Descriptors) Descriptor references | ||
| 107 | for all protocol message types nested within this one. | ||
| 108 | nested_types_by_name: (dict str -> Descriptor) Same Descriptor | ||
| 109 | objects as in |nested_types|, but indexed by "name" attribute | ||
| 110 | in each Descriptor. | ||
| 111 | |||
| 112 | enum_types: (list of EnumDescriptors) EnumDescriptor references | ||
| 113 | for all enums contained within this type. | ||
| 114 | enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor | ||
| 115 | objects as in |enum_types|, but indexed by "name" attribute | ||
| 116 | in each EnumDescriptor. | ||
| 117 | enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping | ||
| 118 | from enum value name to EnumValueDescriptor for that value. | ||
| 119 | |||
| 120 | extensions: (list of FieldDescriptor) All extensions defined directly | ||
| 121 | within this message type (NOT within a nested type). | ||
| 122 | extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor | ||
| 123 | objects as |extensions|, but indexed by "name" attribute of each | ||
| 124 | FieldDescriptor. | ||
| 125 | |||
| 126 | options: (descriptor_pb2.MessageOptions) Protocol message options or None | ||
| 127 | to use default message options. | ||
| 128 | """ | ||
| 129 | |||
| 130 | def __init__(self, name, full_name, filename, containing_type, | ||
| 131 | fields, nested_types, enum_types, extensions, options=None): | ||
| 132 | """Arguments to __init__() are as described in the description | ||
| 133 | of Descriptor fields above. | ||
| 134 | """ | ||
| 135 | super(Descriptor, self).__init__(options, 'MessageOptions') | ||
| 136 | self.name = name | ||
| 137 | self.full_name = full_name | ||
| 138 | self.filename = filename | ||
| 139 | self.containing_type = containing_type | ||
| 140 | |||
| 141 | # We have fields in addition to fields_by_name and fields_by_number, | ||
| 142 | # so that: | ||
| 143 | # 1. Clients can index fields by "order in which they're listed." | ||
| 144 | # 2. Clients can easily iterate over all fields with the terse | ||
| 145 | # syntax: for f in descriptor.fields: ... | ||
| 146 | self.fields = fields | ||
| 147 | for field in self.fields: | ||
| 148 | field.containing_type = self | ||
| 149 | self.fields_by_number = dict((f.number, f) for f in fields) | ||
| 150 | self.fields_by_name = dict((f.name, f) for f in fields) | ||
| 151 | |||
| 152 | self.nested_types = nested_types | ||
| 153 | self.nested_types_by_name = dict((t.name, t) for t in nested_types) | ||
| 154 | |||
| 155 | self.enum_types = enum_types | ||
| 156 | for enum_type in self.enum_types: | ||
| 157 | enum_type.containing_type = self | ||
| 158 | self.enum_types_by_name = dict((t.name, t) for t in enum_types) | ||
| 159 | self.enum_values_by_name = dict( | ||
| 160 | (v.name, v) for t in enum_types for v in t.values) | ||
| 161 | |||
| 162 | self.extensions = extensions | ||
| 163 | for extension in self.extensions: | ||
| 164 | extension.extension_scope = self | ||
| 165 | self.extensions_by_name = dict((f.name, f) for f in extensions) | ||
| 166 | |||
| 167 | |||
| 168 | # TODO(robinson): We should have aggressive checking here, | ||
| 169 | # for example: | ||
| 170 | # * If you specify a repeated field, you should not be allowed | ||
| 171 | # to specify a default value. | ||
| 172 | # * [Other examples here as needed]. | ||
| 173 | # | ||
| 174 | # TODO(robinson): for this and other *Descriptor classes, we | ||
| 175 | # might also want to lock things down aggressively (e.g., | ||
| 176 | # prevent clients from setting the attributes). Having | ||
| 177 | # stronger invariants here in general will reduce the number | ||
| 178 | # of runtime checks we must do in reflection.py... | ||
| 179 | class FieldDescriptor(DescriptorBase): | ||
| 180 | |||
| 181 | """Descriptor for a single field in a .proto file. | ||
| 182 | |||
| 183 | A FieldDescriptor instance has the following attriubtes: | ||
| 184 | |||
| 185 | name: (str) Name of this field, exactly as it appears in .proto. | ||
| 186 | full_name: (str) Name of this field, including containing scope. This is | ||
| 187 | particularly relevant for extensions. | ||
| 188 | index: (int) Dense, 0-indexed index giving the order that this | ||
| 189 | field textually appears within its message in the .proto file. | ||
| 190 | number: (int) Tag number declared for this field in the .proto file. | ||
| 191 | |||
| 192 | type: (One of the TYPE_* constants below) Declared type. | ||
| 193 | cpp_type: (One of the CPPTYPE_* constants below) C++ type used to | ||
| 194 | represent this field. | ||
| 195 | |||
| 196 | label: (One of the LABEL_* constants below) Tells whether this | ||
| 197 | field is optional, required, or repeated. | ||
| 198 | default_value: (Varies) Default value of this field. Only | ||
| 199 | meaningful for non-repeated scalar fields. Repeated fields | ||
| 200 | should always set this to [], and non-repeated composite | ||
| 201 | fields should always set this to None. | ||
| 202 | |||
| 203 | containing_type: (Descriptor) Descriptor of the protocol message | ||
| 204 | type that contains this field. Set by the Descriptor constructor | ||
| 205 | if we're passed into one. | ||
| 206 | Somewhat confusingly, for extension fields, this is the | ||
| 207 | descriptor of the EXTENDED message, not the descriptor | ||
| 208 | of the message containing this field. (See is_extension and | ||
| 209 | extension_scope below). | ||
| 210 | message_type: (Descriptor) If a composite field, a descriptor | ||
| 211 | of the message type contained in this field. Otherwise, this is None. | ||
| 212 | enum_type: (EnumDescriptor) If this field contains an enum, a | ||
| 213 | descriptor of that enum. Otherwise, this is None. | ||
| 214 | |||
| 215 | is_extension: True iff this describes an extension field. | ||
| 216 | extension_scope: (Descriptor) Only meaningful if is_extension is True. | ||
| 217 | Gives the message that immediately contains this extension field. | ||
| 218 | Will be None iff we're a top-level (file-level) extension field. | ||
| 219 | |||
| 220 | options: (descriptor_pb2.FieldOptions) Protocol message field options or | ||
| 221 | None to use default field options. | ||
| 222 | """ | ||
| 223 | |||
| 224 | # Must be consistent with C++ FieldDescriptor::Type enum in | ||
| 225 | # descriptor.h. | ||
| 226 | # | ||
| 227 | # TODO(robinson): Find a way to eliminate this repetition. | ||
| 228 | TYPE_DOUBLE = 1 | ||
| 229 | TYPE_FLOAT = 2 | ||
| 230 | TYPE_INT64 = 3 | ||
| 231 | TYPE_UINT64 = 4 | ||
| 232 | TYPE_INT32 = 5 | ||
| 233 | TYPE_FIXED64 = 6 | ||
| 234 | TYPE_FIXED32 = 7 | ||
| 235 | TYPE_BOOL = 8 | ||
| 236 | TYPE_STRING = 9 | ||
| 237 | TYPE_GROUP = 10 | ||
| 238 | TYPE_MESSAGE = 11 | ||
| 239 | TYPE_BYTES = 12 | ||
| 240 | TYPE_UINT32 = 13 | ||
| 241 | TYPE_ENUM = 14 | ||
| 242 | 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 | |||
| 299 | class 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 | |||
| 339 | class 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 | |||
| 363 | class 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 | |||
| 395 | class 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 | |||
| 426 | def _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; | ||
