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

http://github.com/tomahawk-player/tomahawk · Python · 598 lines · 445 code · 20 blank · 133 comment · 22 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. """Descriptors essentially contain exactly the information found in a .proto
  31. file, in types that make this information accessible in Python.
  32. """
  33. __author__ = 'robinson@google.com (Will Robinson)'
  34. from google.protobuf.internal import api_implementation
  35. if api_implementation.Type() == 'cpp':
  36. from google.protobuf.internal import cpp_message
  37. class Error(Exception):
  38. """Base error for this module."""
  39. class DescriptorBase(object):
  40. """Descriptors base class.
  41. This class is the base of all descriptor classes. It provides common options
  42. related functionaility.
  43. Attributes:
  44. has_options: True if the descriptor has non-default options. Usually it
  45. is not necessary to read this -- just call GetOptions() which will
  46. happily return the default instance. However, it's sometimes useful
  47. for efficiency, and also useful inside the protobuf implementation to
  48. avoid some bootstrapping issues.
  49. """
  50. def __init__(self, options, options_class_name):
  51. """Initialize the descriptor given its options message and the name of the
  52. class of the options message. The name of the class is required in case
  53. the options message is None and has to be created.
  54. """
  55. self._options = options
  56. self._options_class_name = options_class_name
  57. # Does this descriptor have non-default options?
  58. self.has_options = options is not None
  59. def GetOptions(self):
  60. """Retrieves descriptor options.
  61. This method returns the options set or creates the default options for the
  62. descriptor.
  63. """
  64. if self._options:
  65. return self._options
  66. from google.protobuf import descriptor_pb2
  67. try:
  68. options_class = getattr(descriptor_pb2, self._options_class_name)
  69. except AttributeError:
  70. raise RuntimeError('Unknown options class name %s!' %
  71. (self._options_class_name))
  72. self._options = options_class()
  73. return self._options
  74. class _NestedDescriptorBase(DescriptorBase):
  75. """Common class for descriptors that can be nested."""
  76. def __init__(self, options, options_class_name, name, full_name,
  77. file, containing_type, serialized_start=None,
  78. serialized_end=None):
  79. """Constructor.
  80. Args:
  81. options: Protocol message options or None
  82. to use default message options.
  83. options_class_name: (str) The class name of the above options.
  84. name: (str) Name of this protocol message type.
  85. full_name: (str) Fully-qualified name of this protocol message type,
  86. which will include protocol "package" name and the name of any
  87. enclosing types.
  88. file: (FileDescriptor) Reference to file info.
  89. containing_type: if provided, this is a nested descriptor, with this
  90. descriptor as parent, otherwise None.
  91. serialized_start: The start index (inclusive) in block in the
  92. file.serialized_pb that describes this descriptor.
  93. serialized_end: The end index (exclusive) in block in the
  94. file.serialized_pb that describes this descriptor.
  95. """
  96. super(_NestedDescriptorBase, self).__init__(
  97. options, options_class_name)
  98. self.name = name
  99. # TODO(falk): Add function to calculate full_name instead of having it in
  100. # memory?
  101. self.full_name = full_name
  102. self.file = file
  103. self.containing_type = containing_type
  104. self._serialized_start = serialized_start
  105. self._serialized_end = serialized_end
  106. def GetTopLevelContainingType(self):
  107. """Returns the root if this is a nested type, or itself if its the root."""
  108. desc = self
  109. while desc.containing_type is not None:
  110. desc = desc.containing_type
  111. return desc
  112. def CopyToProto(self, proto):
  113. """Copies this to the matching proto in descriptor_pb2.
  114. Args:
  115. proto: An empty proto instance from descriptor_pb2.
  116. Raises:
  117. Error: If self couldnt be serialized, due to to few constructor arguments.
  118. """
  119. if (self.file is not None and
  120. self._serialized_start is not None and
  121. self._serialized_end is not None):
  122. proto.ParseFromString(self.file.serialized_pb[
  123. self._serialized_start:self._serialized_end])
  124. else:
  125. raise Error('Descriptor does not contain serialization.')
  126. class Descriptor(_NestedDescriptorBase):
  127. """Descriptor for a protocol message type.
  128. A Descriptor instance has the following attributes:
  129. name: (str) Name of this protocol message type.
  130. full_name: (str) Fully-qualified name of this protocol message type,
  131. which will include protocol "package" name and the name of any
  132. enclosing types.
  133. containing_type: (Descriptor) Reference to the descriptor of the
  134. type containing us, or None if this is top-level.
  135. fields: (list of FieldDescriptors) Field descriptors for all
  136. fields in this type.
  137. fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor
  138. objects as in |fields|, but indexed by "number" attribute in each
  139. FieldDescriptor.
  140. fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor
  141. objects as in |fields|, but indexed by "name" attribute in each
  142. FieldDescriptor.
  143. nested_types: (list of Descriptors) Descriptor references
  144. for all protocol message types nested within this one.
  145. nested_types_by_name: (dict str -> Descriptor) Same Descriptor
  146. objects as in |nested_types|, but indexed by "name" attribute
  147. in each Descriptor.
  148. enum_types: (list of EnumDescriptors) EnumDescriptor references
  149. for all enums contained within this type.
  150. enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor
  151. objects as in |enum_types|, but indexed by "name" attribute
  152. in each EnumDescriptor.
  153. enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping
  154. from enum value name to EnumValueDescriptor for that value.
  155. extensions: (list of FieldDescriptor) All extensions defined directly
  156. within this message type (NOT within a nested type).
  157. extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor
  158. objects as |extensions|, but indexed by "name" attribute of each
  159. FieldDescriptor.
  160. is_extendable: Does this type define any extension ranges?
  161. options: (descriptor_pb2.MessageOptions) Protocol message options or None
  162. to use default message options.
  163. file: (FileDescriptor) Reference to file descriptor.
  164. """
  165. def __init__(self, name, full_name, filename, containing_type, fields,
  166. nested_types, enum_types, extensions, options=None,
  167. is_extendable=True, extension_ranges=None, file=None,
  168. serialized_start=None, serialized_end=None):
  169. """Arguments to __init__() are as described in the description
  170. of Descriptor fields above.
  171. Note that filename is an obsolete argument, that is not used anymore.
  172. Please use file.name to access this as an attribute.
  173. """
  174. super(Descriptor, self).__init__(
  175. options, 'MessageOptions', name, full_name, file,
  176. containing_type, serialized_start=serialized_start,
  177. serialized_end=serialized_start)
  178. # We have fields in addition to fields_by_name and fields_by_number,
  179. # so that:
  180. # 1. Clients can index fields by "order in which they're listed."
  181. # 2. Clients can easily iterate over all fields with the terse
  182. # syntax: for f in descriptor.fields: ...
  183. self.fields = fields
  184. for field in self.fields:
  185. field.containing_type = self
  186. self.fields_by_number = dict((f.number, f) for f in fields)
  187. self.fields_by_name = dict((f.name, f) for f in fields)
  188. self.nested_types = nested_types
  189. self.nested_types_by_name = dict((t.name, t) for t in nested_types)
  190. self.enum_types = enum_types
  191. for enum_type in self.enum_types:
  192. enum_type.containing_type = self
  193. self.enum_types_by_name = dict((t.name, t) for t in enum_types)
  194. self.enum_values_by_name = dict(
  195. (v.name, v) for t in enum_types for v in t.values)
  196. self.extensions = extensions
  197. for extension in self.extensions:
  198. extension.extension_scope = self
  199. self.extensions_by_name = dict((f.name, f) for f in extensions)
  200. self.is_extendable = is_extendable
  201. self.extension_ranges = extension_ranges
  202. self._serialized_start = serialized_start
  203. self._serialized_end = serialized_end
  204. def CopyToProto(self, proto):
  205. """Copies this to a descriptor_pb2.DescriptorProto.
  206. Args:
  207. proto: An empty descriptor_pb2.DescriptorProto.
  208. """
  209. # This function is overriden to give a better doc comment.
  210. super(Descriptor, self).CopyToProto(proto)
  211. # TODO(robinson): We should have aggressive checking here,
  212. # for example:
  213. # * If you specify a repeated field, you should not be allowed
  214. # to specify a default value.
  215. # * [Other examples here as needed].
  216. #
  217. # TODO(robinson): for this and other *Descriptor classes, we
  218. # might also want to lock things down aggressively (e.g.,
  219. # prevent clients from setting the attributes). Having
  220. # stronger invariants here in general will reduce the number
  221. # of runtime checks we must do in reflection.py...
  222. class FieldDescriptor(DescriptorBase):
  223. """Descriptor for a single field in a .proto file.
  224. A FieldDescriptor instance has the following attriubtes:
  225. name: (str) Name of this field, exactly as it appears in .proto.
  226. full_name: (str) Name of this field, including containing scope. This is
  227. particularly relevant for extensions.
  228. index: (int) Dense, 0-indexed index giving the order that this
  229. field textually appears within its message in the .proto file.
  230. number: (int) Tag number declared for this field in the .proto file.
  231. type: (One of the TYPE_* constants below) Declared type.
  232. cpp_type: (One of the CPPTYPE_* constants below) C++ type used to
  233. represent this field.
  234. label: (One of the LABEL_* constants below) Tells whether this
  235. field is optional, required, or repeated.
  236. has_default_value: (bool) True if this field has a default value defined,
  237. otherwise false.
  238. default_value: (Varies) Default value of this field. Only
  239. meaningful for non-repeated scalar fields. Repeated fields
  240. should always set this to [], and non-repeated composite
  241. fields should always set this to None.
  242. containing_type: (Descriptor) Descriptor of the protocol message
  243. type that contains this field. Set by the Descriptor constructor
  244. if we're passed into one.
  245. Somewhat confusingly, for extension fields, this is the
  246. descriptor of the EXTENDED message, not the descriptor
  247. of the message containing this field. (See is_extension and
  248. extension_scope below).
  249. message_type: (Descriptor) If a composite field, a descriptor
  250. of the message type contained in this field. Otherwise, this is None.
  251. enum_type: (EnumDescriptor) If this field contains an enum, a
  252. descriptor of that enum. Otherwise, this is None.
  253. is_extension: True iff this describes an extension field.
  254. extension_scope: (Descriptor) Only meaningful if is_extension is True.
  255. Gives the message that immediately contains this extension field.
  256. Will be None iff we're a top-level (file-level) extension field.
  257. options: (descriptor_pb2.FieldOptions) Protocol message field options or
  258. None to use default field options.
  259. """
  260. # Must be consistent with C++ FieldDescriptor::Type enum in
  261. # descriptor.h.
  262. #
  263. # TODO(robinson): Find a way to eliminate this repetition.
  264. TYPE_DOUBLE = 1
  265. TYPE_FLOAT = 2
  266. TYPE_INT64 = 3
  267. TYPE_UINT64 = 4
  268. TYPE_INT32 = 5
  269. TYPE_FIXED64 = 6
  270. TYPE_FIXED32 = 7
  271. TYPE_BOOL = 8
  272. TYPE_STRING = 9
  273. TYPE_GROUP = 10
  274. TYPE_MESSAGE = 11
  275. TYPE_BYTES = 12
  276. TYPE_UINT32 = 13
  277. TYPE_ENUM = 14
  278. TYPE_SFIXED32 = 15
  279. TYPE_SFIXED64 = 16
  280. TYPE_SINT32 = 17
  281. TYPE_SINT64 = 18
  282. MAX_TYPE = 18
  283. # Must be consistent with C++ FieldDescriptor::CppType enum in
  284. # descriptor.h.
  285. #
  286. # TODO(robinson): Find a way to eliminate this repetition.
  287. CPPTYPE_INT32 = 1
  288. CPPTYPE_INT64 = 2
  289. CPPTYPE_UINT32 = 3
  290. CPPTYPE_UINT64 = 4
  291. CPPTYPE_DOUBLE = 5
  292. CPPTYPE_FLOAT = 6
  293. CPPTYPE_BOOL = 7
  294. CPPTYPE_ENUM = 8
  295. CPPTYPE_STRING = 9
  296. CPPTYPE_MESSAGE = 10
  297. MAX_CPPTYPE = 10
  298. # Must be consistent with C++ FieldDescriptor::Label enum in
  299. # descriptor.h.
  300. #
  301. # TODO(robinson): Find a way to eliminate this repetition.
  302. LABEL_OPTIONAL = 1
  303. LABEL_REQUIRED = 2
  304. LABEL_REPEATED = 3
  305. MAX_LABEL = 3
  306. def __init__(self, name, full_name, index, number, type, cpp_type, label,
  307. default_value, message_type, enum_type, containing_type,
  308. is_extension, extension_scope, options=None,
  309. has_default_value=True):
  310. """The arguments are as described in the description of FieldDescriptor
  311. attributes above.
  312. Note that containing_type may be None, and may be set later if necessary
  313. (to deal with circular references between message types, for example).
  314. Likewise for extension_scope.
  315. """
  316. super(FieldDescriptor, self).__init__(options, 'FieldOptions')
  317. self.name = name
  318. self.full_name = full_name
  319. self.index = index
  320. self.number = number
  321. self.type = type
  322. self.cpp_type = cpp_type
  323. self.label = label
  324. self.has_default_value = has_default_value
  325. self.default_value = default_value
  326. self.containing_type = containing_type
  327. self.message_type = message_type
  328. self.enum_type = enum_type
  329. self.is_extension = is_extension
  330. self.extension_scope = extension_scope
  331. if api_implementation.Type() == 'cpp':
  332. if is_extension:
  333. self._cdescriptor = cpp_message.GetExtensionDescriptor(full_name)
  334. else:
  335. self._cdescriptor = cpp_message.GetFieldDescriptor(full_name)
  336. else:
  337. self._cdescriptor = None
  338. class EnumDescriptor(_NestedDescriptorBase):
  339. """Descriptor for an enum defined in a .proto file.
  340. An EnumDescriptor instance has the following attributes:
  341. name: (str) Name of the enum type.
  342. full_name: (str) Full name of the type, including package name
  343. and any enclosing type(s).
  344. values: (list of EnumValueDescriptors) List of the values
  345. in this enum.
  346. values_by_name: (dict str -> EnumValueDescriptor) Same as |values|,
  347. but indexed by the "name" field of each EnumValueDescriptor.
  348. values_by_number: (dict int -> EnumValueDescriptor) Same as |values|,
  349. but indexed by the "number" field of each EnumValueDescriptor.
  350. containing_type: (Descriptor) Descriptor of the immediate containing
  351. type of this enum, or None if this is an enum defined at the
  352. top level in a .proto file. Set by Descriptor's constructor
  353. if we're passed into one.
  354. file: (FileDescriptor) Reference to file descriptor.
  355. options: (descriptor_pb2.EnumOptions) Enum options message or
  356. None to use default enum options.
  357. """
  358. def __init__(self, name, full_name, filename, values,
  359. containing_type=None, options=None, file=None,
  360. serialized_start=None, serialized_end=None):
  361. """Arguments are as described in the attribute description above.
  362. Note that filename is an obsolete argument, that is not used anymore.
  363. Please use file.name to access this as an attribute.
  364. """
  365. super(EnumDescriptor, self).__init__(
  366. options, 'EnumOptions', name, full_name, file,
  367. containing_type, serialized_start=serialized_start,
  368. serialized_end=serialized_start)
  369. self.values = values
  370. for value in self.values:
  371. value.type = self
  372. self.values_by_name = dict((v.name, v) for v in values)
  373. self.values_by_number = dict((v.number, v) for v in values)
  374. self._serialized_start = serialized_start
  375. self._serialized_end = serialized_end
  376. def CopyToProto(self, proto):
  377. """Copies this to a descriptor_pb2.EnumDescriptorProto.
  378. Args:
  379. proto: An empty descriptor_pb2.EnumDescriptorProto.
  380. """
  381. # This function is overriden to give a better doc comment.
  382. super(EnumDescriptor, self).CopyToProto(proto)
  383. class EnumValueDescriptor(DescriptorBase):
  384. """Descriptor for a single value within an enum.
  385. name: (str) Name of this value.
  386. index: (int) Dense, 0-indexed index giving the order that this
  387. value appears textually within its enum in the .proto file.
  388. number: (int) Actual number assigned to this enum value.
  389. type: (EnumDescriptor) EnumDescriptor to which this value
  390. belongs. Set by EnumDescriptor's constructor if we're
  391. passed into one.
  392. options: (descriptor_pb2.EnumValueOptions) Enum value options message or
  393. None to use default enum value options options.
  394. """
  395. def __init__(self, name, index, number, type=None, options=None):
  396. """Arguments are as described in the attribute description above."""
  397. super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions')
  398. self.name = name
  399. self.index = index
  400. self.number = number
  401. self.type = type
  402. class ServiceDescriptor(_NestedDescriptorBase):
  403. """Descriptor for a service.
  404. name: (str) Name of the service.
  405. full_name: (str) Full name of the service, including package name.
  406. index: (int) 0-indexed index giving the order that this services
  407. definition appears withing the .proto file.
  408. methods: (list of MethodDescriptor) List of methods provided by this
  409. service.
  410. options: (descriptor_pb2.ServiceOptions) Service options message or
  411. None to use default service options.
  412. file: (FileDescriptor) Reference to file info.
  413. """
  414. def __init__(self, name, full_name, index, methods, options=None, file=None,
  415. serialized_start=None, serialized_end=None):
  416. super(ServiceDescriptor, self).__init__(
  417. options, 'ServiceOptions', name, full_name, file,
  418. None, serialized_start=serialized_start,
  419. serialized_end=serialized_end)
  420. self.index = index
  421. self.methods = methods
  422. # Set the containing service for each method in this service.
  423. for method in self.methods:
  424. method.containing_service = self
  425. def FindMethodByName(self, name):
  426. """Searches for the specified method, and returns its descriptor."""
  427. for method in self.methods:
  428. if name == method.name:
  429. return method
  430. return None
  431. def CopyToProto(self, proto):
  432. """Copies this to a descriptor_pb2.ServiceDescriptorProto.
  433. Args:
  434. proto: An empty descriptor_pb2.ServiceDescriptorProto.
  435. """
  436. # This function is overriden to give a better doc comment.
  437. super(ServiceDescriptor, self).CopyToProto(proto)
  438. class MethodDescriptor(DescriptorBase):
  439. """Descriptor for a method in a service.
  440. name: (str) Name of the method within the service.
  441. full_name: (str) Full name of method.
  442. index: (int) 0-indexed index of the method inside the service.
  443. containing_service: (ServiceDescriptor) The service that contains this
  444. method.
  445. input_type: The descriptor of the message that this method accepts.
  446. output_type: The descriptor of the message that this method returns.
  447. options: (descriptor_pb2.MethodOptions) Method options message or
  448. None to use default method options.
  449. """
  450. def __init__(self, name, full_name, index, containing_service,
  451. input_type, output_type, options=None):
  452. """The arguments are as described in the description of MethodDescriptor
  453. attributes above.
  454. Note that containing_service may be None, and may be set later if necessary.
  455. """
  456. super(MethodDescriptor, self).__init__(options, 'MethodOptions')
  457. self.name = name
  458. self.full_name = full_name
  459. self.index = index
  460. self.containing_service = containing_service
  461. self.input_type = input_type
  462. self.output_type = output_type
  463. class FileDescriptor(DescriptorBase):
  464. """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto.
  465. name: name of file, relative to root of source tree.
  466. package: name of the package
  467. serialized_pb: (str) Byte string of serialized
  468. descriptor_pb2.FileDescriptorProto.
  469. """
  470. def __init__(self, name, package, options=None, serialized_pb=None):
  471. """Constructor."""
  472. super(FileDescriptor, self).__init__(options, 'FileOptions')
  473. self.message_types_by_name = {}
  474. self.name = name
  475. self.package = package
  476. self.serialized_pb = serialized_pb
  477. if (api_implementation.Type() == 'cpp' and
  478. self.serialized_pb is not None):
  479. cpp_message.BuildFile(self.serialized_pb)
  480. def CopyToProto(self, proto):
  481. """Copies this to a descriptor_pb2.FileDescriptorProto.
  482. Args:
  483. proto: An empty descriptor_pb2.FileDescriptorProto.
  484. """
  485. proto.ParseFromString(self.serialized_pb)
  486. def _ParseOptions(message, string):
  487. """Parses serialized options.
  488. This helper function is used to parse serialized options in generated
  489. proto2 files. It must not be used outside proto2.
  490. """
  491. message.ParseFromString(string)
  492. return message