1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 """Provides DescriptorPool to use as a container for proto2 descriptors.
32
33 The DescriptorPool is used in conjection with a DescriptorDatabase to maintain
34 a collection of protocol buffer descriptors for use when dynamically creating
35 message types at runtime.
36
37 For most applications protocol buffers should be used via modules generated by
38 the protocol buffer compiler tool. This should only be used when the type of
39 protocol buffers used in an application or library cannot be predetermined.
40
41 Below is a straightforward example on how to use this class:
42
43 pool = DescriptorPool()
44 file_descriptor_protos = [ ... ]
45 for file_descriptor_proto in file_descriptor_protos:
46 pool.Add(file_descriptor_proto)
47 my_message_descriptor = pool.FindMessageTypeByName('some.package.MessageType')
48
49 The message descriptor can be used in conjunction with the message_factory
50 module in order to create a protocol buffer class that can be encoded and
51 decoded.
52
53 If you want to get a Python class for the specified proto, use the
54 helper functions inside google.protobuf.message_factory
55 directly instead of this class.
56 """
57
58 __author__ = 'matthewtoia@google.com (Matt Toia)'
59
60 import collections
61 import warnings
62
63 from google.protobuf import descriptor
64 from google.protobuf import descriptor_database
65 from google.protobuf import text_encoding
66
67
68 _USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS
72 """Mark functions as deprecated."""
73
74 def NewFunc(*args, **kwargs):
75 warnings.warn(
76 'Call to deprecated function %s(). Note: Do add unlinked descriptors '
77 'to descriptor_pool is wrong. Use Add() or AddSerializedFile() '
78 'instead.' % func.__name__,
79 category=DeprecationWarning)
80 return func(*args, **kwargs)
81 NewFunc.__name__ = func.__name__
82 NewFunc.__doc__ = func.__doc__
83 NewFunc.__dict__.update(func.__dict__)
84 return NewFunc
85
88 """Remove leading period from fully-qualified type name.
89
90 Due to b/13860351 in descriptor_database.py, types in the root namespace are
91 generated with a leading period. This function removes that prefix.
92
93 Args:
94 name: A str, the fully-qualified symbol name.
95
96 Returns:
97 A str, the normalized fully-qualified symbol name.
98 """
99 return name.lstrip('.')
100
103 """Returns the value of the field `options`, or None if it is not set."""
104 if descriptor_proto.HasField('options'):
105 return descriptor_proto.options
106 else:
107 return None
108
111 return (field.is_extension and
112 field.containing_type.has_options and
113 field.containing_type.GetOptions().message_set_wire_format and
114 field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
115 field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL)
116
119 """A collection of protobufs dynamically constructed by descriptor protos."""
120
121 if _USE_C_DESCRIPTORS:
122
123 - def __new__(cls, descriptor_db=None):
126
127 - def __init__(self, descriptor_db=None):
128 """Initializes a Pool of proto buffs.
129
130 The descriptor_db argument to the constructor is provided to allow
131 specialized file descriptor proto lookup code to be triggered on demand. An
132 example would be an implementation which will read and compile a file
133 specified in a call to FindFileByName() and not require the call to Add()
134 at all. Results from this database will be cached internally here as well.
135
136 Args:
137 descriptor_db: A secondary source of file descriptors.
138 """
139
140 self._internal_db = descriptor_database.DescriptorDatabase()
141 self._descriptor_db = descriptor_db
142 self._descriptors = {}
143 self._enum_descriptors = {}
144 self._service_descriptors = {}
145 self._file_descriptors = {}
146 self._toplevel_extensions = {}
147
148
149 self._file_desc_by_toplevel_extension = {}
150 self._top_enum_values = {}
151
152
153
154 self._extensions_by_name = collections.defaultdict(dict)
155 self._extensions_by_number = collections.defaultdict(dict)
156
158 """Check if the descriptor name conflicts with another of the same name.
159
160 Args:
161 desc: Descriptor of a message, enum, service, extension or enum value.
162 desc_name: the full name of desc.
163 file_name: The file name of descriptor.
164 """
165 for register, descriptor_type in [
166 (self._descriptors, descriptor.Descriptor),
167 (self._enum_descriptors, descriptor.EnumDescriptor),
168 (self._service_descriptors, descriptor.ServiceDescriptor),
169 (self._toplevel_extensions, descriptor.FieldDescriptor),
170 (self._top_enum_values, descriptor.EnumValueDescriptor)]:
171 if desc_name in register:
172 old_desc = register[desc_name]
173 if isinstance(old_desc, descriptor.EnumValueDescriptor):
174 old_file = old_desc.type.file.name
175 else:
176 old_file = old_desc.file.name
177
178 if not isinstance(desc, descriptor_type) or (
179 old_file != file_name):
180 error_msg = ('Conflict register for file "' + file_name +
181 '": ' + desc_name +
182 ' is already defined in file "' +
183 old_file + '". Please fix the conflict by adding '
184 'package name on the proto file, or use different '
185 'name for the duplication.')
186 if isinstance(desc, descriptor.EnumValueDescriptor):
187 error_msg += ('\nNote: enum values appear as '
188 'siblings of the enum type instead of '
189 'children of it.')
190
191 raise TypeError(error_msg)
192
193 return
194
195 - def Add(self, file_desc_proto):
196 """Adds the FileDescriptorProto and its types to this pool.
197
198 Args:
199 file_desc_proto: The FileDescriptorProto to add.
200 """
201
202 self._internal_db.Add(file_desc_proto)
203
205 """Adds the FileDescriptorProto and its types to this pool.
206
207 Args:
208 serialized_file_desc_proto: A bytes string, serialization of the
209 FileDescriptorProto to add.
210 """
211
212
213 from google.protobuf import descriptor_pb2
214 file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString(
215 serialized_file_desc_proto)
216 self.Add(file_desc_proto)
217
218
219
220 @_Deprecated
223
224
226 """Adds a Descriptor to the pool, non-recursively.
227
228 If the Descriptor contains nested messages or enums, the caller must
229 explicitly register them. This method also registers the FileDescriptor
230 associated with the message.
231
232 Args:
233 desc: A Descriptor.
234 """
235 if not isinstance(desc, descriptor.Descriptor):
236 raise TypeError('Expected instance of descriptor.Descriptor.')
237
238 self._CheckConflictRegister(desc, desc.full_name, desc.file.name)
239
240 self._descriptors[desc.full_name] = desc
241 self._AddFileDescriptor(desc.file)
242
243
244
245 @_Deprecated
248
249
251 """Adds an EnumDescriptor to the pool.
252
253 This method also registers the FileDescriptor associated with the enum.
254
255 Args:
256 enum_desc: An EnumDescriptor.
257 """
258
259 if not isinstance(enum_desc, descriptor.EnumDescriptor):
260 raise TypeError('Expected instance of descriptor.EnumDescriptor.')
261
262 file_name = enum_desc.file.name
263 self._CheckConflictRegister(enum_desc, enum_desc.full_name, file_name)
264 self._enum_descriptors[enum_desc.full_name] = enum_desc
265
266
267
268
269 if enum_desc.file.package:
270 top_level = (enum_desc.full_name.count('.')
271 - enum_desc.file.package.count('.') == 1)
272 else:
273 top_level = enum_desc.full_name.count('.') == 0
274 if top_level:
275 file_name = enum_desc.file.name
276 package = enum_desc.file.package
277 for enum_value in enum_desc.values:
278 full_name = _NormalizeFullyQualifiedName(
279 '.'.join((package, enum_value.name)))
280 self._CheckConflictRegister(enum_value, full_name, file_name)
281 self._top_enum_values[full_name] = enum_value
282 self._AddFileDescriptor(enum_desc.file)
283
284
285
286 @_Deprecated
289
290
292 """Adds a ServiceDescriptor to the pool.
293
294 Args:
295 service_desc: A ServiceDescriptor.
296 """
297
298 if not isinstance(service_desc, descriptor.ServiceDescriptor):
299 raise TypeError('Expected instance of descriptor.ServiceDescriptor.')
300
301 self._CheckConflictRegister(service_desc, service_desc.full_name,
302 service_desc.file.name)
303 self._service_descriptors[service_desc.full_name] = service_desc
304
305
306
307 @_Deprecated
310
311
313 """Adds a FieldDescriptor describing an extension to the pool.
314
315 Args:
316 extension: A FieldDescriptor.
317
318 Raises:
319 AssertionError: when another extension with the same number extends the
320 same message.
321 TypeError: when the specified extension is not a
322 descriptor.FieldDescriptor.
323 """
324 if not (isinstance(extension, descriptor.FieldDescriptor) and
325 extension.is_extension):
326 raise TypeError('Expected an extension descriptor.')
327
328 if extension.extension_scope is None:
329 self._toplevel_extensions[extension.full_name] = extension
330
331 try:
332 existing_desc = self._extensions_by_number[
333 extension.containing_type][extension.number]
334 except KeyError:
335 pass
336 else:
337 if extension is not existing_desc:
338 raise AssertionError(
339 'Extensions "%s" and "%s" both try to extend message type "%s" '
340 'with field number %d.' %
341 (extension.full_name, existing_desc.full_name,
342 extension.containing_type.full_name, extension.number))
343
344 self._extensions_by_number[extension.containing_type][
345 extension.number] = extension
346 self._extensions_by_name[extension.containing_type][
347 extension.full_name] = extension
348
349
350 if _IsMessageSetExtension(extension):
351 self._extensions_by_name[extension.containing_type][
352 extension.message_type.full_name] = extension
353
354 @_Deprecated
357
358
360 """Adds a FileDescriptor to the pool, non-recursively.
361
362 If the FileDescriptor contains messages or enums, the caller must explicitly
363 register them.
364
365 Args:
366 file_desc: A FileDescriptor.
367 """
368
369 self._AddFileDescriptor(file_desc)
370
371
372
373 for extension in file_desc.extensions_by_name.values():
374 self._file_desc_by_toplevel_extension[
375 extension.full_name] = file_desc
376
378 """Adds a FileDescriptor to the pool, non-recursively.
379
380 If the FileDescriptor contains messages or enums, the caller must explicitly
381 register them.
382
383 Args:
384 file_desc: A FileDescriptor.
385 """
386
387 if not isinstance(file_desc, descriptor.FileDescriptor):
388 raise TypeError('Expected instance of descriptor.FileDescriptor.')
389 self._file_descriptors[file_desc.name] = file_desc
390
392 """Gets a FileDescriptor by file name.
393
394 Args:
395 file_name: The path to the file to get a descriptor for.
396
397 Returns:
398 A FileDescriptor for the named file.
399
400 Raises:
401 KeyError: if the file cannot be found in the pool.
402 """
403
404 try:
405 return self._file_descriptors[file_name]
406 except KeyError:
407 pass
408
409 try:
410 file_proto = self._internal_db.FindFileByName(file_name)
411 except KeyError as error:
412 if self._descriptor_db:
413 file_proto = self._descriptor_db.FindFileByName(file_name)
414 else:
415 raise error
416 if not file_proto:
417 raise KeyError('Cannot find a file named %s' % file_name)
418 return self._ConvertFileProtoToFileDescriptor(file_proto)
419
421 """Gets the FileDescriptor for the file containing the specified symbol.
422
423 Args:
424 symbol: The name of the symbol to search for.
425
426 Returns:
427 A FileDescriptor that contains the specified symbol.
428
429 Raises:
430 KeyError: if the file cannot be found in the pool.
431 """
432
433 symbol = _NormalizeFullyQualifiedName(symbol)
434 try:
435 return self._InternalFindFileContainingSymbol(symbol)
436 except KeyError:
437 pass
438
439 try:
440
441 self._FindFileContainingSymbolInDb(symbol)
442 return self._InternalFindFileContainingSymbol(symbol)
443 except KeyError:
444 raise KeyError('Cannot find a file containing %s' % symbol)
445
447 """Gets the already built FileDescriptor containing the specified symbol.
448
449 Args:
450 symbol: The name of the symbol to search for.
451
452 Returns:
453 A FileDescriptor that contains the specified symbol.
454
455 Raises:
456 KeyError: if the file cannot be found in the pool.
457 """
458 try:
459 return self._descriptors[symbol].file
460 except KeyError:
461 pass
462
463 try:
464 return self._enum_descriptors[symbol].file
465 except KeyError:
466 pass
467
468 try:
469 return self._service_descriptors[symbol].file
470 except KeyError:
471 pass
472
473 try:
474 return self._top_enum_values[symbol].type.file
475 except KeyError:
476 pass
477
478 try:
479 return self._file_desc_by_toplevel_extension[symbol]
480 except KeyError:
481 pass
482
483
484 top_name, _, sub_name = symbol.rpartition('.')
485 try:
486 message = self.FindMessageTypeByName(top_name)
487 assert (sub_name in message.extensions_by_name or
488 sub_name in message.fields_by_name or
489 sub_name in message.enum_values_by_name)
490 return message.file
491 except (KeyError, AssertionError):
492 raise KeyError('Cannot find a file containing %s' % symbol)
493
495 """Loads the named descriptor from the pool.
496
497 Args:
498 full_name: The full name of the descriptor to load.
499
500 Returns:
501 The descriptor for the named type.
502
503 Raises:
504 KeyError: if the message cannot be found in the pool.
505 """
506
507 full_name = _NormalizeFullyQualifiedName(full_name)
508 if full_name not in self._descriptors:
509 self._FindFileContainingSymbolInDb(full_name)
510 return self._descriptors[full_name]
511
513 """Loads the named enum descriptor from the pool.
514
515 Args:
516 full_name: The full name of the enum descriptor to load.
517
518 Returns:
519 The enum descriptor for the named type.
520
521 Raises:
522 KeyError: if the enum cannot be found in the pool.
523 """
524
525 full_name = _NormalizeFullyQualifiedName(full_name)
526 if full_name not in self._enum_descriptors:
527 self._FindFileContainingSymbolInDb(full_name)
528 return self._enum_descriptors[full_name]
529
531 """Loads the named field descriptor from the pool.
532
533 Args:
534 full_name: The full name of the field descriptor to load.
535
536 Returns:
537 The field descriptor for the named field.
538
539 Raises:
540 KeyError: if the field cannot be found in the pool.
541 """
542 full_name = _NormalizeFullyQualifiedName(full_name)
543 message_name, _, field_name = full_name.rpartition('.')
544 message_descriptor = self.FindMessageTypeByName(message_name)
545 return message_descriptor.fields_by_name[field_name]
546
548 """Loads the named oneof descriptor from the pool.
549
550 Args:
551 full_name: The full name of the oneof descriptor to load.
552
553 Returns:
554 The oneof descriptor for the named oneof.
555
556 Raises:
557 KeyError: if the oneof cannot be found in the pool.
558 """
559 full_name = _NormalizeFullyQualifiedName(full_name)
560 message_name, _, oneof_name = full_name.rpartition('.')
561 message_descriptor = self.FindMessageTypeByName(message_name)
562 return message_descriptor.oneofs_by_name[oneof_name]
563
565 """Loads the named extension descriptor from the pool.
566
567 Args:
568 full_name: The full name of the extension descriptor to load.
569
570 Returns:
571 A FieldDescriptor, describing the named extension.
572
573 Raises:
574 KeyError: if the extension cannot be found in the pool.
575 """
576 full_name = _NormalizeFullyQualifiedName(full_name)
577 try:
578
579
580
581
582 return self._toplevel_extensions[full_name]
583 except KeyError:
584 pass
585 message_name, _, extension_name = full_name.rpartition('.')
586 try:
587
588 scope = self.FindMessageTypeByName(message_name)
589 except KeyError:
590
591 scope = self._FindFileContainingSymbolInDb(full_name)
592 return scope.extensions_by_name[extension_name]
593
595 """Gets the extension of the specified message with the specified number.
596
597 Extensions have to be registered to this pool by calling
598 AddExtensionDescriptor.
599
600 Args:
601 message_descriptor: descriptor of the extended message.
602 number: integer, number of the extension field.
603
604 Returns:
605 A FieldDescriptor describing the extension.
606
607 Raises:
608 KeyError: when no extension with the given number is known for the
609 specified message.
610 """
611 try:
612 return self._extensions_by_number[message_descriptor][number]
613 except KeyError:
614 self._TryLoadExtensionFromDB(message_descriptor, number)
615 return self._extensions_by_number[message_descriptor][number]
616
618 """Gets all the known extension of a given message.
619
620 Extensions have to be registered to this pool by calling
621 AddExtensionDescriptor.
622
623 Args:
624 message_descriptor: descriptor of the extended message.
625
626 Returns:
627 A list of FieldDescriptor describing the extensions.
628 """
629
630 if self._descriptor_db and hasattr(
631 self._descriptor_db, 'FindAllExtensionNumbers'):
632 full_name = message_descriptor.full_name
633 all_numbers = self._descriptor_db.FindAllExtensionNumbers(full_name)
634 for number in all_numbers:
635 if number in self._extensions_by_number[message_descriptor]:
636 continue
637 self._TryLoadExtensionFromDB(message_descriptor, number)
638
639 return list(self._extensions_by_number[message_descriptor].values())
640
642 """Try to Load extensions from decriptor db.
643
644 Args:
645 message_descriptor: descriptor of the extended message.
646 number: the extension number that needs to be loaded.
647 """
648 if not self._descriptor_db:
649 return
650
651 if not hasattr(
652 self._descriptor_db, 'FindFileContainingExtension'):
653 return
654
655 full_name = message_descriptor.full_name
656 file_proto = self._descriptor_db.FindFileContainingExtension(
657 full_name, number)
658
659 if file_proto is None:
660 return
661
662 try:
663 file_desc = self._ConvertFileProtoToFileDescriptor(file_proto)
664 for extension in file_desc.extensions_by_name.values():
665 self._extensions_by_number[extension.containing_type][
666 extension.number] = extension
667 self._extensions_by_name[extension.containing_type][
668 extension.full_name] = extension
669 for message_type in file_desc.message_types_by_name.values():
670 for extension in message_type.extensions:
671 self._extensions_by_number[extension.containing_type][
672 extension.number] = extension
673 self._extensions_by_name[extension.containing_type][
674 extension.full_name] = extension
675 except:
676 warn_msg = ('Unable to load proto file %s for extension number %d.' %
677 (file_proto.name, number))
678 warnings.warn(warn_msg, RuntimeWarning)
679
681 """Loads the named service descriptor from the pool.
682
683 Args:
684 full_name: The full name of the service descriptor to load.
685
686 Returns:
687 The service descriptor for the named service.
688
689 Raises:
690 KeyError: if the service cannot be found in the pool.
691 """
692 full_name = _NormalizeFullyQualifiedName(full_name)
693 if full_name not in self._service_descriptors:
694 self._FindFileContainingSymbolInDb(full_name)
695 return self._service_descriptors[full_name]
696
698 """Loads the named service method descriptor from the pool.
699
700 Args:
701 full_name: The full name of the method descriptor to load.
702
703 Returns:
704 The method descriptor for the service method.
705
706 Raises:
707 KeyError: if the method cannot be found in the pool.
708 """
709 full_name = _NormalizeFullyQualifiedName(full_name)
710 service_name, _, method_name = full_name.rpartition('.')
711 service_descriptor = self.FindServiceByName(service_name)
712 return service_descriptor.methods_by_name[method_name]
713
715 """Finds the file in descriptor DB containing the specified symbol.
716
717 Args:
718 symbol: The name of the symbol to search for.
719
720 Returns:
721 A FileDescriptor that contains the specified symbol.
722
723 Raises:
724 KeyError: if the file cannot be found in the descriptor database.
725 """
726 try:
727 file_proto = self._internal_db.FindFileContainingSymbol(symbol)
728 except KeyError as error:
729 if self._descriptor_db:
730 file_proto = self._descriptor_db.FindFileContainingSymbol(symbol)
731 else:
732 raise error
733 if not file_proto:
734 raise KeyError('Cannot find a file containing %s' % symbol)
735 return self._ConvertFileProtoToFileDescriptor(file_proto)
736
738 """Creates a FileDescriptor from a proto or returns a cached copy.
739
740 This method also has the side effect of loading all the symbols found in
741 the file into the appropriate dictionaries in the pool.
742
743 Args:
744 file_proto: The proto to convert.
745
746 Returns:
747 A FileDescriptor matching the passed in proto.
748 """
749 if file_proto.name not in self._file_descriptors:
750 built_deps = list(self._GetDeps(file_proto.dependency))
751 direct_deps = [self.FindFileByName(n) for n in file_proto.dependency]
752 public_deps = [direct_deps[i] for i in file_proto.public_dependency]
753
754 file_descriptor = descriptor.FileDescriptor(
755 pool=self,
756 name=file_proto.name,
757 package=file_proto.package,
758 syntax=file_proto.syntax,
759 options=_OptionsOrNone(file_proto),
760 serialized_pb=file_proto.SerializeToString(),
761 dependencies=direct_deps,
762 public_dependencies=public_deps)
763 scope = {}
764
765
766
767
768
769 for dependency in built_deps:
770 scope.update(self._ExtractSymbols(
771 dependency.message_types_by_name.values()))
772 scope.update((_PrefixWithDot(enum.full_name), enum)
773 for enum in dependency.enum_types_by_name.values())
774
775 for message_type in file_proto.message_type:
776 message_desc = self._ConvertMessageDescriptor(
777 message_type, file_proto.package, file_descriptor, scope,
778 file_proto.syntax)
779 file_descriptor.message_types_by_name[message_desc.name] = (
780 message_desc)
781
782 for enum_type in file_proto.enum_type:
783 file_descriptor.enum_types_by_name[enum_type.name] = (
784 self._ConvertEnumDescriptor(enum_type, file_proto.package,
785 file_descriptor, None, scope, True))
786
787 for index, extension_proto in enumerate(file_proto.extension):
788 extension_desc = self._MakeFieldDescriptor(
789 extension_proto, file_proto.package, index, file_descriptor,
790 is_extension=True)
791 extension_desc.containing_type = self._GetTypeFromScope(
792 file_descriptor.package, extension_proto.extendee, scope)
793 self._SetFieldType(extension_proto, extension_desc,
794 file_descriptor.package, scope)
795 file_descriptor.extensions_by_name[extension_desc.name] = (
796 extension_desc)
797 self._file_desc_by_toplevel_extension[extension_desc.full_name] = (
798 file_descriptor)
799
800 for desc_proto in file_proto.message_type:
801 self._SetAllFieldTypes(file_proto.package, desc_proto, scope)
802
803 if file_proto.package:
804 desc_proto_prefix = _PrefixWithDot(file_proto.package)
805 else:
806 desc_proto_prefix = ''
807
808 for desc_proto in file_proto.message_type:
809 desc = self._GetTypeFromScope(
810 desc_proto_prefix, desc_proto.name, scope)
811 file_descriptor.message_types_by_name[desc_proto.name] = desc
812
813 for index, service_proto in enumerate(file_proto.service):
814 file_descriptor.services_by_name[service_proto.name] = (
815 self._MakeServiceDescriptor(service_proto, index, scope,
816 file_proto.package, file_descriptor))
817
818 self.Add(file_proto)
819 self._file_descriptors[file_proto.name] = file_descriptor
820
821 return self._file_descriptors[file_proto.name]
822
825 """Adds the proto to the pool in the specified package.
826
827 Args:
828 desc_proto: The descriptor_pb2.DescriptorProto protobuf message.
829 package: The package the proto should be located in.
830 file_desc: The file containing this message.
831 scope: Dict mapping short and full symbols to message and enum types.
832 syntax: string indicating syntax of the file ("proto2" or "proto3")
833
834 Returns:
835 The added descriptor.
836 """
837
838 if package:
839 desc_name = '.'.join((package, desc_proto.name))
840 else:
841 desc_name = desc_proto.name
842
843 if file_desc is None:
844 file_name = None
845 else:
846 file_name = file_desc.name
847
848 if scope is None:
849 scope = {}
850
851 nested = [
852 self._ConvertMessageDescriptor(
853 nested, desc_name, file_desc, scope, syntax)
854 for nested in desc_proto.nested_type]
855 enums = [
856 self._ConvertEnumDescriptor(enum, desc_name, file_desc, None,
857 scope, False)
858 for enum in desc_proto.enum_type]
859 fields = [self._MakeFieldDescriptor(field, desc_name, index, file_desc)
860 for index, field in enumerate(desc_proto.field)]
861 extensions = [
862 self._MakeFieldDescriptor(extension, desc_name, index, file_desc,
863 is_extension=True)
864 for index, extension in enumerate(desc_proto.extension)]
865 oneofs = [
866 descriptor.OneofDescriptor(desc.name, '.'.join((desc_name, desc.name)),
867 index, None, [], desc.options)
868 for index, desc in enumerate(desc_proto.oneof_decl)]
869 extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range]
870 if extension_ranges:
871 is_extendable = True
872 else:
873 is_extendable = False
874 desc = descriptor.Descriptor(
875 name=desc_proto.name,
876 full_name=desc_name,
877 filename=file_name,
878 containing_type=None,
879 fields=fields,
880 oneofs=oneofs,
881 nested_types=nested,
882 enum_types=enums,
883 extensions=extensions,
884 options=_OptionsOrNone(desc_proto),
885 is_extendable=is_extendable,
886 extension_ranges=extension_ranges,
887 file=file_desc,
888 serialized_start=None,
889 serialized_end=None,
890 syntax=syntax)
891 for nested in desc.nested_types:
892 nested.containing_type = desc
893 for enum in desc.enum_types:
894 enum.containing_type = desc
895 for field_index, field_desc in enumerate(desc_proto.field):
896 if field_desc.HasField('oneof_index'):
897 oneof_index = field_desc.oneof_index
898 oneofs[oneof_index].fields.append(fields[field_index])
899 fields[field_index].containing_oneof = oneofs[oneof_index]
900
901 scope[_PrefixWithDot(desc_name)] = desc
902 self._CheckConflictRegister(desc, desc.full_name, desc.file.name)
903 self._descriptors[desc_name] = desc
904 return desc
905
906 - def _ConvertEnumDescriptor(self, enum_proto, package=None, file_desc=None,
907 containing_type=None, scope=None, top_level=False):
908 """Make a protobuf EnumDescriptor given an EnumDescriptorProto protobuf.
909
910 Args:
911 enum_proto: The descriptor_pb2.EnumDescriptorProto protobuf message.
912 package: Optional package name for the new message EnumDescriptor.
913 file_desc: The file containing the enum descriptor.
914 containing_type: The type containing this enum.
915 scope: Scope containing available types.
916 top_level: If True, the enum is a top level symbol. If False, the enum
917 is defined inside a message.
918
919 Returns:
920 The added descriptor
921 """
922
923 if package:
924 enum_name = '.'.join((package, enum_proto.name))
925 else:
926 enum_name = enum_proto.name
927
928 if file_desc is None:
929 file_name = None
930 else:
931 file_name = file_desc.name
932
933 values = [self._MakeEnumValueDescriptor(value, index)
934 for index, value in enumerate(enum_proto.value)]
935 desc = descriptor.EnumDescriptor(name=enum_proto.name,
936 full_name=enum_name,
937 filename=file_name,
938 file=file_desc,
939 values=values,
940 containing_type=containing_type,
941 options=_OptionsOrNone(enum_proto))
942 scope['.%s' % enum_name] = desc
943 self._CheckConflictRegister(desc, desc.full_name, desc.file.name)
944 self._enum_descriptors[enum_name] = desc
945
946
947 if top_level:
948 for value in values:
949 full_name = _NormalizeFullyQualifiedName(
950 '.'.join((package, value.name)))
951 self._CheckConflictRegister(value, full_name, file_name)
952 self._top_enum_values[full_name] = value
953
954 return desc
955
956 - def _MakeFieldDescriptor(self, field_proto, message_name, index,
957 file_desc, is_extension=False):
958 """Creates a field descriptor from a FieldDescriptorProto.
959
960 For message and enum type fields, this method will do a look up
961 in the pool for the appropriate descriptor for that type. If it
962 is unavailable, it will fall back to the _source function to
963 create it. If this type is still unavailable, construction will
964 fail.
965
966 Args:
967 field_proto: The proto describing the field.
968 message_name: The name of the containing message.
969 index: Index of the field
970 file_desc: The file containing the field descriptor.
971 is_extension: Indication that this field is for an extension.
972
973 Returns:
974 An initialized FieldDescriptor object
975 """
976
977 if message_name:
978 full_name = '.'.join((message_name, field_proto.name))
979 else:
980 full_name = field_proto.name
981
982 return descriptor.FieldDescriptor(
983 name=field_proto.name,
984 full_name=full_name,
985 index=index,
986 number=field_proto.number,
987 type=field_proto.type,
988 cpp_type=None,
989 message_type=None,
990 enum_type=None,
991 containing_type=None,
992 label=field_proto.label,
993 has_default_value=False,
994 default_value=None,
995 is_extension=is_extension,
996 extension_scope=None,
997 options=_OptionsOrNone(field_proto),
998 file=file_desc)
999
1001 """Sets all the descriptor's fields's types.
1002
1003 This method also sets the containing types on any extensions.
1004
1005 Args:
1006 package: The current package of desc_proto.
1007 desc_proto: The message descriptor to update.
1008 scope: Enclosing scope of available types.
1009 """
1010
1011 package = _PrefixWithDot(package)
1012
1013 main_desc = self._GetTypeFromScope(package, desc_proto.name, scope)
1014
1015 if package == '.':
1016 nested_package = _PrefixWithDot(desc_proto.name)
1017 else:
1018 nested_package = '.'.join([package, desc_proto.name])
1019
1020 for field_proto, field_desc in zip(desc_proto.field, main_desc.fields):
1021 self._SetFieldType(field_proto, field_desc, nested_package, scope)
1022
1023 for extension_proto, extension_desc in (
1024 zip(desc_proto.extension, main_desc.extensions)):
1025 extension_desc.containing_type = self._GetTypeFromScope(
1026 nested_package, extension_proto.extendee, scope)
1027 self._SetFieldType(extension_proto, extension_desc, nested_package, scope)
1028
1029 for nested_type in desc_proto.nested_type:
1030 self._SetAllFieldTypes(nested_package, nested_type, scope)
1031
1032 - def _SetFieldType(self, field_proto, field_desc, package, scope):
1105
1107 """Creates a enum value descriptor object from a enum value proto.
1108
1109 Args:
1110 value_proto: The proto describing the enum value.
1111 index: The index of the enum value.
1112
1113 Returns:
1114 An initialized EnumValueDescriptor object.
1115 """
1116
1117 return descriptor.EnumValueDescriptor(
1118 name=value_proto.name,
1119 index=index,
1120 number=value_proto.number,
1121 options=_OptionsOrNone(value_proto),
1122 type=None)
1123
1126 """Make a protobuf ServiceDescriptor given a ServiceDescriptorProto.
1127
1128 Args:
1129 service_proto: The descriptor_pb2.ServiceDescriptorProto protobuf message.
1130 service_index: The index of the service in the File.
1131 scope: Dict mapping short and full symbols to message and enum types.
1132 package: Optional package name for the new message EnumDescriptor.
1133 file_desc: The file containing the service descriptor.
1134
1135 Returns:
1136 The added descriptor.
1137 """
1138
1139 if package:
1140 service_name = '.'.join((package, service_proto.name))
1141 else:
1142 service_name = service_proto.name
1143
1144 methods = [self._MakeMethodDescriptor(method_proto, service_name, package,
1145 scope, index)
1146 for index, method_proto in enumerate(service_proto.method)]
1147 desc = descriptor.ServiceDescriptor(name=service_proto.name,
1148 full_name=service_name,
1149 index=service_index,
1150 methods=methods,
1151 options=_OptionsOrNone(service_proto),
1152 file=file_desc)
1153 self._CheckConflictRegister(desc, desc.full_name, desc.file.name)
1154 self._service_descriptors[service_name] = desc
1155 return desc
1156
1159 """Creates a method descriptor from a MethodDescriptorProto.
1160
1161 Args:
1162 method_proto: The proto describing the method.
1163 service_name: The name of the containing service.
1164 package: Optional package name to look up for types.
1165 scope: Scope containing available types.
1166 index: Index of the method in the service.
1167
1168 Returns:
1169 An initialized MethodDescriptor object.
1170 """
1171 full_name = '.'.join((service_name, method_proto.name))
1172 input_type = self._GetTypeFromScope(
1173 package, method_proto.input_type, scope)
1174 output_type = self._GetTypeFromScope(
1175 package, method_proto.output_type, scope)
1176 return descriptor.MethodDescriptor(name=method_proto.name,
1177 full_name=full_name,
1178 index=index,
1179 containing_service=None,
1180 input_type=input_type,
1181 output_type=output_type,
1182 options=_OptionsOrNone(method_proto))
1183
1185 """Pulls out all the symbols from descriptor protos.
1186
1187 Args:
1188 descriptors: The messages to extract descriptors from.
1189 Yields:
1190 A two element tuple of the type name and descriptor object.
1191 """
1192
1193 for desc in descriptors:
1194 yield (_PrefixWithDot(desc.full_name), desc)
1195 for symbol in self._ExtractSymbols(desc.nested_types):
1196 yield symbol
1197 for enum in desc.enum_types:
1198 yield (_PrefixWithDot(enum.full_name), enum)
1199
1201 """Recursively finds dependencies for file protos.
1202
1203 Args:
1204 dependencies: The names of the files being depended on.
1205
1206 Yields:
1207 Each direct and indirect dependency.
1208 """
1209
1210 for dependency in dependencies:
1211 dep_desc = self.FindFileByName(dependency)
1212 yield dep_desc
1213 for parent_dep in dep_desc.dependencies:
1214 yield parent_dep
1215
1217 """Finds a given type name in the current scope.
1218
1219 Args:
1220 package: The package the proto should be located in.
1221 type_name: The name of the type to be found in the scope.
1222 scope: Dict mapping short and full symbols to message and enum types.
1223
1224 Returns:
1225 The descriptor for the requested type.
1226 """
1227 if type_name not in scope:
1228 components = _PrefixWithDot(package).split('.')
1229 while components:
1230 possible_match = '.'.join(components + [type_name])
1231 if possible_match in scope:
1232 type_name = possible_match
1233 break
1234 else:
1235 components.pop(-1)
1236 return scope[type_name]
1237
1240 return name if name.startswith('.') else '.%s' % name
1241
1242
1243 if _USE_C_DESCRIPTORS:
1244
1245
1246
1247 _DEFAULT = descriptor._message.default_pool
1248 else:
1249 _DEFAULT = DescriptorPool()
1254