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 """A database of Python protocol buffer generated symbols.
32
33 SymbolDatabase is the MessageFactory for messages generated at compile time,
34 and makes it easy to create new instances of a registered type, given only the
35 type's protocol buffer symbol name.
36
37 Example usage:
38
39 db = symbol_database.SymbolDatabase()
40
41 # Register symbols of interest, from one or multiple files.
42 db.RegisterFileDescriptor(my_proto_pb2.DESCRIPTOR)
43 db.RegisterMessage(my_proto_pb2.MyMessage)
44 db.RegisterEnumDescriptor(my_proto_pb2.MyEnum.DESCRIPTOR)
45
46 # The database can be used as a MessageFactory, to generate types based on
47 # their name:
48 types = db.GetMessages(['my_proto.proto'])
49 my_message_instance = types['MyMessage']()
50
51 # The database's underlying descriptor pool can be queried, so it's not
52 # necessary to know a type's filename to be able to generate it:
53 filename = db.pool.FindFileContainingSymbol('MyMessage')
54 my_message_instance = db.GetMessages([filename])['MyMessage']()
55
56 # This functionality is also provided directly via a convenience method:
57 my_message_instance = db.GetSymbol('MyMessage')()
58 """
59
60
61 from google.protobuf.internal import api_implementation
62 from google.protobuf import descriptor_pool
63 from google.protobuf import message_factory
64
65
67 """A database of Python generated symbols."""
68
70 """Registers the given message type in the local database.
71
72 Calls to GetSymbol() and GetMessages() will return messages registered here.
73
74 Args:
75 message: a message.Message, to be registered.
76
77 Returns:
78 The provided message.
79 """
80
81 desc = message.DESCRIPTOR
82 self._classes[desc] = message
83 self.RegisterMessageDescriptor(desc)
84 return message
85
87 """Registers the given message descriptor in the local database.
88
89 Args:
90 message_descriptor: a descriptor.MessageDescriptor.
91 """
92 if api_implementation.Type() == 'python':
93
94 self.pool._AddDescriptor(message_descriptor)
95
97 """Registers the given enum descriptor in the local database.
98
99 Args:
100 enum_descriptor: a descriptor.EnumDescriptor.
101
102 Returns:
103 The provided descriptor.
104 """
105 if api_implementation.Type() == 'python':
106
107 self.pool._AddEnumDescriptor(enum_descriptor)
108 return enum_descriptor
109
111 """Registers the given service descriptor in the local database.
112
113 Args:
114 service_descriptor: a descriptor.ServiceDescriptor.
115
116 Returns:
117 The provided descriptor.
118 """
119 if api_implementation.Type() == 'python':
120
121 self.pool._AddServiceDescriptor(service_descriptor)
122
124 """Registers the given file descriptor in the local database.
125
126 Args:
127 file_descriptor: a descriptor.FileDescriptor.
128
129 Returns:
130 The provided descriptor.
131 """
132 if api_implementation.Type() == 'python':
133
134 self.pool._InternalAddFileDescriptor(file_descriptor)
135
137 """Tries to find a symbol in the local database.
138
139 Currently, this method only returns message.Message instances, however, if
140 may be extended in future to support other symbol types.
141
142 Args:
143 symbol: A str, a protocol buffer symbol.
144
145 Returns:
146 A Python class corresponding to the symbol.
147
148 Raises:
149 KeyError: if the symbol could not be found.
150 """
151
152 return self._classes[self.pool.FindMessageTypeByName(symbol)]
153
155
156 """Gets all registered messages from a specified file.
157
158 Only messages already created and registered will be returned; (this is the
159 case for imported _pb2 modules)
160 But unlike MessageFactory, this version also returns already defined nested
161 messages, but does not register any message extensions.
162
163 Args:
164 files: The file names to extract messages from.
165
166 Returns:
167 A dictionary mapping proto names to the message classes.
168
169 Raises:
170 KeyError: if a file could not be found.
171 """
172
173 def _GetAllMessages(desc):
174 """Walk a message Descriptor and recursively yields all message names."""
175 yield desc
176 for msg_desc in desc.nested_types:
177 for nested_desc in _GetAllMessages(msg_desc):
178 yield nested_desc
179
180 result = {}
181 for file_name in files:
182 file_desc = self.pool.FindFileByName(file_name)
183 for msg_desc in file_desc.message_types_by_name.values():
184 for desc in _GetAllMessages(msg_desc):
185 try:
186 result[desc.full_name] = self._classes[desc]
187 except KeyError:
188
189 pass
190 return result
191
192
193 _DEFAULT = SymbolDatabase(pool=descriptor_pool.Default())
194
195
197 """Returns the default SymbolDatabase."""
198 return _DEFAULT
199