Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: third_party/google/protobuf/descriptor.py

Issue 1153333003: Added tools to retrieve CQ builders from a CQ config (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Addressed comments Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 # Needs to stay compatible with Python 2.5 due to GAE.
32 #
33 # Copyright 2007 Google Inc. All Rights Reserved.
34
35 """Descriptors essentially contain exactly the information found in a .proto
36 file, in types that make this information accessible in Python.
37 """
38
39 __author__ = 'robinson@google.com (Will Robinson)'
40
41 from google.protobuf.internal import api_implementation
42
43
44 if api_implementation.Type() == 'cpp':
45 # Used by MakeDescriptor in cpp mode
46 import os
47 import uuid
48
49 if api_implementation.Version() == 2:
50 from google.protobuf.pyext import _message
51 else:
52 from google.protobuf.internal import cpp_message
53
54
55 class Error(Exception):
56 """Base error for this module."""
57
58
59 class TypeTransformationError(Error):
60 """Error transforming between python proto type and corresponding C++ type."""
61
62
63 class DescriptorBase(object):
64
65 """Descriptors base class.
66
67 This class is the base of all descriptor classes. It provides common options
68 related functionaility.
69
70 Attributes:
71 has_options: True if the descriptor has non-default options. Usually it
72 is not necessary to read this -- just call GetOptions() which will
73 happily return the default instance. However, it's sometimes useful
74 for efficiency, and also useful inside the protobuf implementation to
75 avoid some bootstrapping issues.
76 """
77
78 def __init__(self, options, options_class_name):
79 """Initialize the descriptor given its options message and the name of the
80 class of the options message. The name of the class is required in case
81 the options message is None and has to be created.
82 """
83 self._options = options
84 self._options_class_name = options_class_name
85
86 # Does this descriptor have non-default options?
87 self.has_options = options is not None
88
89 def _SetOptions(self, options, options_class_name):
90 """Sets the descriptor's options
91
92 This function is used in generated proto2 files to update descriptor
93 options. It must not be used outside proto2.
94 """
95 self._options = options
96 self._options_class_name = options_class_name
97
98 # Does this descriptor have non-default options?
99 self.has_options = options is not None
100
101 def GetOptions(self):
102 """Retrieves descriptor options.
103
104 This method returns the options set or creates the default options for the
105 descriptor.
106 """
107 if self._options:
108 return self._options
109 from google.protobuf import descriptor_pb2
110 try:
111 options_class = getattr(descriptor_pb2, self._options_class_name)
112 except AttributeError:
113 raise RuntimeError('Unknown options class name %s!' %
114 (self._options_class_name))
115 self._options = options_class()
116 return self._options
117
118
119 class _NestedDescriptorBase(DescriptorBase):
120 """Common class for descriptors that can be nested."""
121
122 def __init__(self, options, options_class_name, name, full_name,
123 file, containing_type, serialized_start=None,
124 serialized_end=None):
125 """Constructor.
126
127 Args:
128 options: Protocol message options or None
129 to use default message options.
130 options_class_name: (str) The class name of the above options.
131
132 name: (str) Name of this protocol message type.
133 full_name: (str) Fully-qualified name of this protocol message type,
134 which will include protocol "package" name and the name of any
135 enclosing types.
136 file: (FileDescriptor) Reference to file info.
137 containing_type: if provided, this is a nested descriptor, with this
138 descriptor as parent, otherwise None.
139 serialized_start: The start index (inclusive) in block in the
140 file.serialized_pb that describes this descriptor.
141 serialized_end: The end index (exclusive) in block in the
142 file.serialized_pb that describes this descriptor.
143 """
144 super(_NestedDescriptorBase, self).__init__(
145 options, options_class_name)
146
147 self.name = name
148 # TODO(falk): Add function to calculate full_name instead of having it in
149 # memory?
150 self.full_name = full_name
151 self.file = file
152 self.containing_type = containing_type
153
154 self._serialized_start = serialized_start
155 self._serialized_end = serialized_end
156
157 def GetTopLevelContainingType(self):
158 """Returns the root if this is a nested type, or itself if its the root."""
159 desc = self
160 while desc.containing_type is not None:
161 desc = desc.containing_type
162 return desc
163
164 def CopyToProto(self, proto):
165 """Copies this to the matching proto in descriptor_pb2.
166
167 Args:
168 proto: An empty proto instance from descriptor_pb2.
169
170 Raises:
171 Error: If self couldnt be serialized, due to to few constructor arguments.
172 """
173 if (self.file is not None and
174 self._serialized_start is not None and
175 self._serialized_end is not None):
176 proto.ParseFromString(self.file.serialized_pb[
177 self._serialized_start:self._serialized_end])
178 else:
179 raise Error('Descriptor does not contain serialization.')
180
181
182 class Descriptor(_NestedDescriptorBase):
183
184 """Descriptor for a protocol message type.
185
186 A Descriptor instance has the following attributes:
187
188 name: (str) Name of this protocol message type.
189 full_name: (str) Fully-qualified name of this protocol message type,
190 which will include protocol "package" name and the name of any
191 enclosing types.
192
193 containing_type: (Descriptor) Reference to the descriptor of the
194 type containing us, or None if this is top-level.
195
196 fields: (list of FieldDescriptors) Field descriptors for all
197 fields in this type.
198 fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor
199 objects as in |fields|, but indexed by "number" attribute in each
200 FieldDescriptor.
201 fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor
202 objects as in |fields|, but indexed by "name" attribute in each
203 FieldDescriptor.
204
205 nested_types: (list of Descriptors) Descriptor references
206 for all protocol message types nested within this one.
207 nested_types_by_name: (dict str -> Descriptor) Same Descriptor
208 objects as in |nested_types|, but indexed by "name" attribute
209 in each Descriptor.
210
211 enum_types: (list of EnumDescriptors) EnumDescriptor references
212 for all enums contained within this type.
213 enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor
214 objects as in |enum_types|, but indexed by "name" attribute
215 in each EnumDescriptor.
216 enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping
217 from enum value name to EnumValueDescriptor for that value.
218
219 extensions: (list of FieldDescriptor) All extensions defined directly
220 within this message type (NOT within a nested type).
221 extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor
222 objects as |extensions|, but indexed by "name" attribute of each
223 FieldDescriptor.
224
225 is_extendable: Does this type define any extension ranges?
226
227 options: (descriptor_pb2.MessageOptions) Protocol message options or None
228 to use default message options.
229
230 oneofs: (list of OneofDescriptor) The list of descriptors for oneof fields
231 in this message.
232 oneofs_by_name: (dict str -> OneofDescriptor) Same objects as in |oneofs|,
233 but indexed by "name" attribute.
234
235 file: (FileDescriptor) Reference to file descriptor.
236 """
237
238 # NOTE(tmarek): The file argument redefining a builtin is nothing we can
239 # fix right now since we don't know how many clients already rely on the
240 # name of the argument.
241 def __init__(self, name, full_name, filename, containing_type, fields,
242 nested_types, enum_types, extensions, options=None,
243 is_extendable=True, extension_ranges=None, oneofs=None,
244 file=None, serialized_start=None, serialized_end=None): # pylint :disable=redefined-builtin
245 """Arguments to __init__() are as described in the description
246 of Descriptor fields above.
247
248 Note that filename is an obsolete argument, that is not used anymore.
249 Please use file.name to access this as an attribute.
250 """
251 super(Descriptor, self).__init__(
252 options, 'MessageOptions', name, full_name, file,
253 containing_type, serialized_start=serialized_start,
254 serialized_end=serialized_end)
255
256 # We have fields in addition to fields_by_name and fields_by_number,
257 # so that:
258 # 1. Clients can index fields by "order in which they're listed."
259 # 2. Clients can easily iterate over all fields with the terse
260 # syntax: for f in descriptor.fields: ...
261 self.fields = fields
262 for field in self.fields:
263 field.containing_type = self
264 self.fields_by_number = dict((f.number, f) for f in fields)
265 self.fields_by_name = dict((f.name, f) for f in fields)
266
267 self.nested_types = nested_types
268 for nested_type in nested_types:
269 nested_type.containing_type = self
270 self.nested_types_by_name = dict((t.name, t) for t in nested_types)
271
272 self.enum_types = enum_types
273 for enum_type in self.enum_types:
274 enum_type.containing_type = self
275 self.enum_types_by_name = dict((t.name, t) for t in enum_types)
276 self.enum_values_by_name = dict(
277 (v.name, v) for t in enum_types for v in t.values)
278
279 self.extensions = extensions
280 for extension in self.extensions:
281 extension.extension_scope = self
282 self.extensions_by_name = dict((f.name, f) for f in extensions)
283 self.is_extendable = is_extendable
284 self.extension_ranges = extension_ranges
285 self.oneofs = oneofs if oneofs is not None else []
286 self.oneofs_by_name = dict((o.name, o) for o in self.oneofs)
287 for oneof in self.oneofs:
288 oneof.containing_type = self
289
290 def EnumValueName(self, enum, value):
291 """Returns the string name of an enum value.
292
293 This is just a small helper method to simplify a common operation.
294
295 Args:
296 enum: string name of the Enum.
297 value: int, value of the enum.
298
299 Returns:
300 string name of the enum value.
301
302 Raises:
303 KeyError if either the Enum doesn't exist or the value is not a valid
304 value for the enum.
305 """
306 return self.enum_types_by_name[enum].values_by_number[value].name
307
308 def CopyToProto(self, proto):
309 """Copies this to a descriptor_pb2.DescriptorProto.
310
311 Args:
312 proto: An empty descriptor_pb2.DescriptorProto.
313 """
314 # This function is overriden to give a better doc comment.
315 super(Descriptor, self).CopyToProto(proto)
316
317
318 # TODO(robinson): We should have aggressive checking here,
319 # for example:
320 # * If you specify a repeated field, you should not be allowed
321 # to specify a default value.
322 # * [Other examples here as needed].
323 #
324 # TODO(robinson): for this and other *Descriptor classes, we
325 # might also want to lock things down aggressively (e.g.,
326 # prevent clients from setting the attributes). Having
327 # stronger invariants here in general will reduce the number
328 # of runtime checks we must do in reflection.py...
329 class FieldDescriptor(DescriptorBase):
330
331 """Descriptor for a single field in a .proto file.
332
333 A FieldDescriptor instance has the following attributes:
334
335 name: (str) Name of this field, exactly as it appears in .proto.
336 full_name: (str) Name of this field, including containing scope. This is
337 particularly relevant for extensions.
338 index: (int) Dense, 0-indexed index giving the order that this
339 field textually appears within its message in the .proto file.
340 number: (int) Tag number declared for this field in the .proto file.
341
342 type: (One of the TYPE_* constants below) Declared type.
343 cpp_type: (One of the CPPTYPE_* constants below) C++ type used to
344 represent this field.
345
346 label: (One of the LABEL_* constants below) Tells whether this
347 field is optional, required, or repeated.
348 has_default_value: (bool) True if this field has a default value defined,
349 otherwise false.
350 default_value: (Varies) Default value of this field. Only
351 meaningful for non-repeated scalar fields. Repeated fields
352 should always set this to [], and non-repeated composite
353 fields should always set this to None.
354
355 containing_type: (Descriptor) Descriptor of the protocol message
356 type that contains this field. Set by the Descriptor constructor
357 if we're passed into one.
358 Somewhat confusingly, for extension fields, this is the
359 descriptor of the EXTENDED message, not the descriptor
360 of the message containing this field. (See is_extension and
361 extension_scope below).
362 message_type: (Descriptor) If a composite field, a descriptor
363 of the message type contained in this field. Otherwise, this is None.
364 enum_type: (EnumDescriptor) If this field contains an enum, a
365 descriptor of that enum. Otherwise, this is None.
366
367 is_extension: True iff this describes an extension field.
368 extension_scope: (Descriptor) Only meaningful if is_extension is True.
369 Gives the message that immediately contains this extension field.
370 Will be None iff we're a top-level (file-level) extension field.
371
372 options: (descriptor_pb2.FieldOptions) Protocol message field options or
373 None to use default field options.
374
375 containing_oneof: (OneofDescriptor) If the field is a member of a oneof
376 union, contains its descriptor. Otherwise, None.
377 """
378
379 # Must be consistent with C++ FieldDescriptor::Type enum in
380 # descriptor.h.
381 #
382 # TODO(robinson): Find a way to eliminate this repetition.
383 TYPE_DOUBLE = 1
384 TYPE_FLOAT = 2
385 TYPE_INT64 = 3
386 TYPE_UINT64 = 4
387 TYPE_INT32 = 5
388 TYPE_FIXED64 = 6
389 TYPE_FIXED32 = 7
390 TYPE_BOOL = 8
391 TYPE_STRING = 9
392 TYPE_GROUP = 10
393 TYPE_MESSAGE = 11
394 TYPE_BYTES = 12
395 TYPE_UINT32 = 13
396 TYPE_ENUM = 14
397 TYPE_SFIXED32 = 15
398 TYPE_SFIXED64 = 16
399 TYPE_SINT32 = 17
400 TYPE_SINT64 = 18
401 MAX_TYPE = 18
402
403 # Must be consistent with C++ FieldDescriptor::CppType enum in
404 # descriptor.h.
405 #
406 # TODO(robinson): Find a way to eliminate this repetition.
407 CPPTYPE_INT32 = 1
408 CPPTYPE_INT64 = 2
409 CPPTYPE_UINT32 = 3
410 CPPTYPE_UINT64 = 4
411 CPPTYPE_DOUBLE = 5
412 CPPTYPE_FLOAT = 6
413 CPPTYPE_BOOL = 7
414 CPPTYPE_ENUM = 8
415 CPPTYPE_STRING = 9
416 CPPTYPE_MESSAGE = 10
417 MAX_CPPTYPE = 10
418
419 _PYTHON_TO_CPP_PROTO_TYPE_MAP = {
420 TYPE_DOUBLE: CPPTYPE_DOUBLE,
421 TYPE_FLOAT: CPPTYPE_FLOAT,
422 TYPE_ENUM: CPPTYPE_ENUM,
423 TYPE_INT64: CPPTYPE_INT64,
424 TYPE_SINT64: CPPTYPE_INT64,
425 TYPE_SFIXED64: CPPTYPE_INT64,
426 TYPE_UINT64: CPPTYPE_UINT64,
427 TYPE_FIXED64: CPPTYPE_UINT64,
428 TYPE_INT32: CPPTYPE_INT32,
429 TYPE_SFIXED32: CPPTYPE_INT32,
430 TYPE_SINT32: CPPTYPE_INT32,
431 TYPE_UINT32: CPPTYPE_UINT32,
432 TYPE_FIXED32: CPPTYPE_UINT32,
433 TYPE_BYTES: CPPTYPE_STRING,
434 TYPE_STRING: CPPTYPE_STRING,
435 TYPE_BOOL: CPPTYPE_BOOL,
436 TYPE_MESSAGE: CPPTYPE_MESSAGE,
437 TYPE_GROUP: CPPTYPE_MESSAGE
438 }
439
440 # Must be consistent with C++ FieldDescriptor::Label enum in
441 # descriptor.h.
442 #
443 # TODO(robinson): Find a way to eliminate this repetition.
444 LABEL_OPTIONAL = 1
445 LABEL_REQUIRED = 2
446 LABEL_REPEATED = 3
447 MAX_LABEL = 3
448
449 # Must be consistent with C++ constants kMaxNumber, kFirstReservedNumber,
450 # and kLastReservedNumber in descriptor.h
451 MAX_FIELD_NUMBER = (1 << 29) - 1
452 FIRST_RESERVED_FIELD_NUMBER = 19000
453 LAST_RESERVED_FIELD_NUMBER = 19999
454
455 def __init__(self, name, full_name, index, number, type, cpp_type, label,
456 default_value, message_type, enum_type, containing_type,
457 is_extension, extension_scope, options=None,
458 has_default_value=True, containing_oneof=None):
459 """The arguments are as described in the description of FieldDescriptor
460 attributes above.
461
462 Note that containing_type may be None, and may be set later if necessary
463 (to deal with circular references between message types, for example).
464 Likewise for extension_scope.
465 """
466 super(FieldDescriptor, self).__init__(options, 'FieldOptions')
467 self.name = name
468 self.full_name = full_name
469 self.index = index
470 self.number = number
471 self.type = type
472 self.cpp_type = cpp_type
473 self.label = label
474 self.has_default_value = has_default_value
475 self.default_value = default_value
476 self.containing_type = containing_type
477 self.message_type = message_type
478 self.enum_type = enum_type
479 self.is_extension = is_extension
480 self.extension_scope = extension_scope
481 self.containing_oneof = containing_oneof
482 if api_implementation.Type() == 'cpp':
483 if is_extension:
484 if api_implementation.Version() == 2:
485 # pylint: disable=protected-access
486 self._cdescriptor = (
487 _message.Message._GetExtensionDescriptor(full_name))
488 # pylint: enable=protected-access
489 else:
490 self._cdescriptor = cpp_message.GetExtensionDescriptor(full_name)
491 else:
492 if api_implementation.Version() == 2:
493 # pylint: disable=protected-access
494 self._cdescriptor = _message.Message._GetFieldDescriptor(full_name)
495 # pylint: enable=protected-access
496 else:
497 self._cdescriptor = cpp_message.GetFieldDescriptor(full_name)
498 else:
499 self._cdescriptor = None
500
501 @staticmethod
502 def ProtoTypeToCppProtoType(proto_type):
503 """Converts from a Python proto type to a C++ Proto Type.
504
505 The Python ProtocolBuffer classes specify both the 'Python' datatype and the
506 'C++' datatype - and they're not the same. This helper method should
507 translate from one to another.
508
509 Args:
510 proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*)
511 Returns:
512 descriptor.FieldDescriptor.CPPTYPE_*, the C++ type.
513 Raises:
514 TypeTransformationError: when the Python proto type isn't known.
515 """
516 try:
517 return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type]
518 except KeyError:
519 raise TypeTransformationError('Unknown proto_type: %s' % proto_type)
520
521
522 class EnumDescriptor(_NestedDescriptorBase):
523
524 """Descriptor for an enum defined in a .proto file.
525
526 An EnumDescriptor instance has the following attributes:
527
528 name: (str) Name of the enum type.
529 full_name: (str) Full name of the type, including package name
530 and any enclosing type(s).
531
532 values: (list of EnumValueDescriptors) List of the values
533 in this enum.
534 values_by_name: (dict str -> EnumValueDescriptor) Same as |values|,
535 but indexed by the "name" field of each EnumValueDescriptor.
536 values_by_number: (dict int -> EnumValueDescriptor) Same as |values|,
537 but indexed by the "number" field of each EnumValueDescriptor.
538 containing_type: (Descriptor) Descriptor of the immediate containing
539 type of this enum, or None if this is an enum defined at the
540 top level in a .proto file. Set by Descriptor's constructor
541 if we're passed into one.
542 file: (FileDescriptor) Reference to file descriptor.
543 options: (descriptor_pb2.EnumOptions) Enum options message or
544 None to use default enum options.
545 """
546
547 def __init__(self, name, full_name, filename, values,
548 containing_type=None, options=None, file=None,
549 serialized_start=None, serialized_end=None):
550 """Arguments are as described in the attribute description above.
551
552 Note that filename is an obsolete argument, that is not used anymore.
553 Please use file.name to access this as an attribute.
554 """
555 super(EnumDescriptor, self).__init__(
556 options, 'EnumOptions', name, full_name, file,
557 containing_type, serialized_start=serialized_start,
558 serialized_end=serialized_end)
559
560 self.values = values
561 for value in self.values:
562 value.type = self
563 self.values_by_name = dict((v.name, v) for v in values)
564 self.values_by_number = dict((v.number, v) for v in values)
565
566 def CopyToProto(self, proto):
567 """Copies this to a descriptor_pb2.EnumDescriptorProto.
568
569 Args:
570 proto: An empty descriptor_pb2.EnumDescriptorProto.
571 """
572 # This function is overriden to give a better doc comment.
573 super(EnumDescriptor, self).CopyToProto(proto)
574
575
576 class EnumValueDescriptor(DescriptorBase):
577
578 """Descriptor for a single value within an enum.
579
580 name: (str) Name of this value.
581 index: (int) Dense, 0-indexed index giving the order that this
582 value appears textually within its enum in the .proto file.
583 number: (int) Actual number assigned to this enum value.
584 type: (EnumDescriptor) EnumDescriptor to which this value
585 belongs. Set by EnumDescriptor's constructor if we're
586 passed into one.
587 options: (descriptor_pb2.EnumValueOptions) Enum value options message or
588 None to use default enum value options options.
589 """
590
591 def __init__(self, name, index, number, type=None, options=None):
592 """Arguments are as described in the attribute description above."""
593 super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions')
594 self.name = name
595 self.index = index
596 self.number = number
597 self.type = type
598
599
600 class OneofDescriptor(object):
601 """Descriptor for a oneof field.
602
603 name: (str) Name of the oneof field.
604 full_name: (str) Full name of the oneof field, including package name.
605 index: (int) 0-based index giving the order of the oneof field inside
606 its containing type.
607 containing_type: (Descriptor) Descriptor of the protocol message
608 type that contains this field. Set by the Descriptor constructor
609 if we're passed into one.
610 fields: (list of FieldDescriptor) The list of field descriptors this
611 oneof can contain.
612 """
613
614 def __init__(self, name, full_name, index, containing_type, fields):
615 """Arguments are as described in the attribute description above."""
616 self.name = name
617 self.full_name = full_name
618 self.index = index
619 self.containing_type = containing_type
620 self.fields = fields
621
622
623 class ServiceDescriptor(_NestedDescriptorBase):
624
625 """Descriptor for a service.
626
627 name: (str) Name of the service.
628 full_name: (str) Full name of the service, including package name.
629 index: (int) 0-indexed index giving the order that this services
630 definition appears withing the .proto file.
631 methods: (list of MethodDescriptor) List of methods provided by this
632 service.
633 options: (descriptor_pb2.ServiceOptions) Service options message or
634 None to use default service options.
635 file: (FileDescriptor) Reference to file info.
636 """
637
638 def __init__(self, name, full_name, index, methods, options=None, file=None,
639 serialized_start=None, serialized_end=None):
640 super(ServiceDescriptor, self).__init__(
641 options, 'ServiceOptions', name, full_name, file,
642 None, serialized_start=serialized_start,
643 serialized_end=serialized_end)
644 self.index = index
645 self.methods = methods
646 # Set the containing service for each method in this service.
647 for method in self.methods:
648 method.containing_service = self
649
650 def FindMethodByName(self, name):
651 """Searches for the specified method, and returns its descriptor."""
652 for method in self.methods:
653 if name == method.name:
654 return method
655 return None
656
657 def CopyToProto(self, proto):
658 """Copies this to a descriptor_pb2.ServiceDescriptorProto.
659
660 Args:
661 proto: An empty descriptor_pb2.ServiceDescriptorProto.
662 """
663 # This function is overriden to give a better doc comment.
664 super(ServiceDescriptor, self).CopyToProto(proto)
665
666
667 class MethodDescriptor(DescriptorBase):
668
669 """Descriptor for a method in a service.
670
671 name: (str) Name of the method within the service.
672 full_name: (str) Full name of method.
673 index: (int) 0-indexed index of the method inside the service.
674 containing_service: (ServiceDescriptor) The service that contains this
675 method.
676 input_type: The descriptor of the message that this method accepts.
677 output_type: The descriptor of the message that this method returns.
678 options: (descriptor_pb2.MethodOptions) Method options message or
679 None to use default method options.
680 """
681
682 def __init__(self, name, full_name, index, containing_service,
683 input_type, output_type, options=None):
684 """The arguments are as described in the description of MethodDescriptor
685 attributes above.
686
687 Note that containing_service may be None, and may be set later if necessary.
688 """
689 super(MethodDescriptor, self).__init__(options, 'MethodOptions')
690 self.name = name
691 self.full_name = full_name
692 self.index = index
693 self.containing_service = containing_service
694 self.input_type = input_type
695 self.output_type = output_type
696
697
698 class FileDescriptor(DescriptorBase):
699 """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto.
700
701 Note that enum_types_by_name, extensions_by_name, and dependencies
702 fields are only set by the message_factory module, and not by the
703 generated proto code.
704
705 name: name of file, relative to root of source tree.
706 package: name of the package
707 serialized_pb: (str) Byte string of serialized
708 descriptor_pb2.FileDescriptorProto.
709 dependencies: List of other FileDescriptors this FileDescriptor depends on.
710 message_types_by_name: Dict of message names of their descriptors.
711 enum_types_by_name: Dict of enum names and their descriptors.
712 extensions_by_name: Dict of extension names and their descriptors.
713 """
714
715 def __init__(self, name, package, options=None, serialized_pb=None,
716 dependencies=None):
717 """Constructor."""
718 super(FileDescriptor, self).__init__(options, 'FileOptions')
719
720 self.message_types_by_name = {}
721 self.name = name
722 self.package = package
723 self.serialized_pb = serialized_pb
724
725 self.enum_types_by_name = {}
726 self.extensions_by_name = {}
727 self.dependencies = (dependencies or [])
728
729 if (api_implementation.Type() == 'cpp' and
730 self.serialized_pb is not None):
731 if api_implementation.Version() == 2:
732 # pylint: disable=protected-access
733 _message.Message._BuildFile(self.serialized_pb)
734 # pylint: enable=protected-access
735 else:
736 cpp_message.BuildFile(self.serialized_pb)
737
738 def CopyToProto(self, proto):
739 """Copies this to a descriptor_pb2.FileDescriptorProto.
740
741 Args:
742 proto: An empty descriptor_pb2.FileDescriptorProto.
743 """
744 proto.ParseFromString(self.serialized_pb)
745
746
747 def _ParseOptions(message, string):
748 """Parses serialized options.
749
750 This helper function is used to parse serialized options in generated
751 proto2 files. It must not be used outside proto2.
752 """
753 message.ParseFromString(string)
754 return message
755
756
757 def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True):
758 """Make a protobuf Descriptor given a DescriptorProto protobuf.
759
760 Handles nested descriptors. Note that this is limited to the scope of defining
761 a message inside of another message. Composite fields can currently only be
762 resolved if the message is defined in the same scope as the field.
763
764 Args:
765 desc_proto: The descriptor_pb2.DescriptorProto protobuf message.
766 package: Optional package name for the new message Descriptor (string).
767 build_file_if_cpp: Update the C++ descriptor pool if api matches.
768 Set to False on recursion, so no duplicates are created.
769 Returns:
770 A Descriptor for protobuf messages.
771 """
772 if api_implementation.Type() == 'cpp' and build_file_if_cpp:
773 # The C++ implementation requires all descriptors to be backed by the same
774 # definition in the C++ descriptor pool. To do this, we build a
775 # FileDescriptorProto with the same definition as this descriptor and build
776 # it into the pool.
777 from google.protobuf import descriptor_pb2
778 file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
779 file_descriptor_proto.message_type.add().MergeFrom(desc_proto)
780
781 # Generate a random name for this proto file to prevent conflicts with
782 # any imported ones. We need to specify a file name so BuildFile accepts
783 # our FileDescriptorProto, but it is not important what that file name
784 # is actually set to.
785 proto_name = str(uuid.uuid4())
786
787 if package:
788 file_descriptor_proto.name = os.path.join(package.replace('.', '/'),
789 proto_name + '.proto')
790 file_descriptor_proto.package = package
791 else:
792 file_descriptor_proto.name = proto_name + '.proto'
793
794 if api_implementation.Version() == 2:
795 # pylint: disable=protected-access
796 _message.Message._BuildFile(file_descriptor_proto.SerializeToString())
797 # pylint: enable=protected-access
798 else:
799 cpp_message.BuildFile(file_descriptor_proto.SerializeToString())
800
801 full_message_name = [desc_proto.name]
802 if package: full_message_name.insert(0, package)
803
804 # Create Descriptors for enum types
805 enum_types = {}
806 for enum_proto in desc_proto.enum_type:
807 full_name = '.'.join(full_message_name + [enum_proto.name])
808 enum_desc = EnumDescriptor(
809 enum_proto.name, full_name, None, [
810 EnumValueDescriptor(enum_val.name, ii, enum_val.number)
811 for ii, enum_val in enumerate(enum_proto.value)])
812 enum_types[full_name] = enum_desc
813
814 # Create Descriptors for nested types
815 nested_types = {}
816 for nested_proto in desc_proto.nested_type:
817 full_name = '.'.join(full_message_name + [nested_proto.name])
818 # Nested types are just those defined inside of the message, not all types
819 # used by fields in the message, so no loops are possible here.
820 nested_desc = MakeDescriptor(nested_proto,
821 package='.'.join(full_message_name),
822 build_file_if_cpp=False)
823 nested_types[full_name] = nested_desc
824
825 fields = []
826 for field_proto in desc_proto.field:
827 full_name = '.'.join(full_message_name + [field_proto.name])
828 enum_desc = None
829 nested_desc = None
830 if field_proto.HasField('type_name'):
831 type_name = field_proto.type_name
832 full_type_name = '.'.join(full_message_name +
833 [type_name[type_name.rfind('.')+1:]])
834 if full_type_name in nested_types:
835 nested_desc = nested_types[full_type_name]
836 elif full_type_name in enum_types:
837 enum_desc = enum_types[full_type_name]
838 # Else type_name references a non-local type, which isn't implemented
839 field = FieldDescriptor(
840 field_proto.name, full_name, field_proto.number - 1,
841 field_proto.number, field_proto.type,
842 FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type),
843 field_proto.label, None, nested_desc, enum_desc, None, False, None,
844 has_default_value=False)
845 fields.append(field)
846
847 desc_name = '.'.join(full_message_name)
848 return Descriptor(desc_proto.name, desc_name, None, None, fields,
849 nested_types.values(), enum_types.values(), [])
OLDNEW
« no previous file with comments | « third_party/google/protobuf/compiler/plugin_pb2.py ('k') | third_party/google/protobuf/descriptor_database.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698