PageRenderTime 40ms CodeModel.GetById 10ms app.highlight 23ms RepoModel.GetById 2ms app.codeStats 0ms

/thirdparty/breakpad/third_party/protobuf/protobuf/python/google/protobuf/descriptor.py

http://github.com/tomahawk-player/tomahawk
Python | 598 lines | 542 code | 12 blank | 44 comment | 10 complexity | 9dba86fd760d005ec031e858bdc72357 MD5 | raw file
  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"""Descriptors essentially contain exactly the information found in a .proto
 32file, in types that make this information accessible in Python.
 33"""
 34
 35__author__ = 'robinson@google.com (Will Robinson)'
 36
 37
 38from google.protobuf.internal import api_implementation
 39
 40
 41if api_implementation.Type() == 'cpp':
 42  from google.protobuf.internal import cpp_message
 43
 44
 45class Error(Exception):
 46  """Base error for this module."""
 47
 48
 49class 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.
 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.
 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
 72    # Does this descriptor have non-default options?
 73    self.has_options = options is not None
 74
 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
 93class _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
156class Descriptor(_NestedDescriptorBase):
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
167    containing_type: (Descriptor) Reference to the descriptor of the
168      type containing us, or None if this is top-level.
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
199    is_extendable:  Does this type define any extension ranges?
200
201    options: (descriptor_pb2.MessageOptions) Protocol message options or None
202      to use default message options.
203
204    file: (FileDescriptor) Reference to file descriptor.
205  """
206
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):
211    """Arguments to __init__() are as described in the description
212    of Descriptor fields above.
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.
216    """
217    super(Descriptor, self).__init__(
218        options, 'MessageOptions', name, full_name, file,
219        containing_type, serialized_start=serialized_start,
220        serialized_end=serialized_start)
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)
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)
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...
274class 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.
293    has_default_value: (bool) True if this field has a default value defined,
294      otherwise false.
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,
372               is_extension, extension_scope, options=None,
373               has_default_value=True):
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
389    self.has_default_value = has_default_value
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
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
403
404
405class EnumDescriptor(_NestedDescriptorBase):
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).
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.
425    file: (FileDescriptor) Reference to file descriptor.
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,
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
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)
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)
460
461
462class 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
486class ServiceDescriptor(_NestedDescriptorBase):
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.
498    file: (FileDescriptor) Reference to file info.
499  """
500
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)
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
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
529
530class 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
561class 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
574    self.message_types_by_name = {}
575    self.name = name
576    self.package = package
577    self.serialized_pb = serialized_pb
578    if (api_implementation.Type() == 'cpp' and
579        self.serialized_pb is not None):
580      cpp_message.BuildFile(self.serialized_pb)
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
591def _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)
598  return message