31 """Provides a factory class for generating dynamic messages.
33 The easiest way to use this class is if you have access to the FileDescriptor
34 protos containing the messages you want to create you can just do the following:
36 message_classes = message_factory.GetMessages(iterable_of_file_descriptors)
37 my_proto_instance = message_classes['some.proto.package.MessageName']()
40 __author__ =
'matthewtoia@google.com (Matt Toia)'
46 if api_implementation.Type() ==
'cpp':
53 _GENERATED_PROTOCOL_MESSAGE_TYPE = message_impl.GeneratedProtocolMessageType
56 class MessageFactory(object):
57 """Factory for creating Proto2 messages from descriptors in a pool."""
60 """Initializes a new factory."""
67 """Obtains a proto2 message class based on the passed in descriptor.
69 Passing a descriptor with a fully qualified name matching a previous
70 invocation will cause the same class to be returned.
73 descriptor: The descriptor to build from.
76 A class describing the passed in descriptor.
83 self.
_classes[descriptor] = result_class
88 """Builds a proto2 message class based on the passed in descriptor.
90 Don't call this function directly, it always creates a new class. Call
91 GetPrototype() instead. This method is meant to be overridden in subblasses
92 to perform additional operations on the newly constructed class.
95 descriptor: The descriptor to build from.
98 A class describing the passed in descriptor.
100 descriptor_name = descriptor.name
105 'DESCRIPTOR': descriptor,
109 result_class._FACTORY = self
112 self.
_classes[descriptor] = result_class
113 for field
in descriptor.fields:
114 if field.message_type:
116 for extension
in result_class.DESCRIPTOR.extensions:
117 if extension.containing_type
not in self.
_classes:
119 extended_class = self.
_classes[extension.containing_type]
120 extended_class.RegisterExtension(extension)
124 """Gets all the messages from a specified file.
126 This will find and resolve dependencies, failing if the descriptor
127 pool cannot satisfy them.
130 files: The file names to extract messages from.
133 A dictionary mapping proto names to the message classes. This will include
134 any dependent messages as well as any messages defined in the same file as
138 for file_name
in files:
140 for desc
in file_desc.message_types_by_name.values():
152 for extension
in file_desc.extensions_by_name.values():
153 if extension.containing_type
not in self.
_classes:
155 extended_class = self.
_classes[extension.containing_type]
156 extended_class.RegisterExtension(extension)
164 """Builds a dictionary of all the messages available in a set of files.
167 file_protos: Iterable of FileDescriptorProto to build messages out of.
170 A dictionary mapping proto names to the message classes. This will include
171 any dependent messages as well as any messages defined in the same file as
176 file_by_name = {file_proto.name: file_proto
for file_proto
in file_protos}
177 def _AddFile(file_proto):
178 for dependency
in file_proto.dependency:
179 if dependency
in file_by_name:
181 _AddFile(file_by_name.pop(dependency))
182 _FACTORY.pool.Add(file_proto)
184 _AddFile(file_by_name.popitem()[1])
185 return _FACTORY.GetMessages([file_proto.name
for file_proto
in file_protos])