diff options
Diffstat (limited to 'froofle/protobuf/service_reflection.py')
-rw-r--r-- | froofle/protobuf/service_reflection.py | 289 |
1 files changed, 0 insertions, 289 deletions
diff --git a/froofle/protobuf/service_reflection.py b/froofle/protobuf/service_reflection.py deleted file mode 100644 index bdd6bad5..00000000 --- a/froofle/protobuf/service_reflection.py +++ /dev/null | |||
@@ -1,289 +0,0 @@ | |||
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 | """Contains metaclasses used to create protocol service and service stub | ||
32 | classes from ServiceDescriptor objects at runtime. | ||
33 | |||
34 | The GeneratedServiceType and GeneratedServiceStubType metaclasses are used to | ||
35 | inject all useful functionality into the classes output by the protocol | ||
36 | compiler at compile-time. | ||
37 | """ | ||
38 | |||
39 | __author__ = 'petar@google.com (Petar Petrov)' | ||
40 | |||
41 | |||
42 | class GeneratedServiceType(type): | ||
43 | |||
44 | """Metaclass for service classes created at runtime from ServiceDescriptors. | ||
45 | |||
46 | Implementations for all methods described in the Service class are added here | ||
47 | by this class. We also create properties to allow getting/setting all fields | ||
48 | in the protocol message. | ||
49 | |||
50 | The protocol compiler currently uses this metaclass to create protocol service | ||
51 | classes at runtime. Clients can also manually create their own classes at | ||
52 | runtime, as in this example: | ||
53 | |||
54 | mydescriptor = ServiceDescriptor(.....) | ||
55 | class MyProtoService(service.Service): | ||
56 | __metaclass__ = GeneratedServiceType | ||
57 | DESCRIPTOR = mydescriptor | ||
58 | myservice_instance = MyProtoService() | ||
59 | ... | ||
60 | """ | ||
61 | |||
62 | _DESCRIPTOR_KEY = 'DESCRIPTOR' | ||
63 | |||
64 | def __init__(cls, name, bases, dictionary): | ||
65 | """Creates a message service class. | ||
66 | |||
67 | Args: | ||
68 | name: Name of the class (ignored, but required by the metaclass | ||
69 | protocol). | ||
70 | bases: Base classes of the class being constructed. | ||
71 | dictionary: The class dictionary of the class being constructed. | ||
72 | dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object | ||
73 | describing this protocol service type. | ||
74 | """ | ||
75 | # Don't do anything if this class doesn't have a descriptor. This happens | ||
76 | # when a service class is subclassed. | ||
77 | if GeneratedServiceType._DESCRIPTOR_KEY not in dictionary: | ||
78 | return | ||
79 | descriptor = dictionary[GeneratedServiceType._DESCRIPTOR_KEY] | ||
80 | service_builder = _ServiceBuilder(descriptor) | ||
81 | service_builder.BuildService(cls) | ||
82 | |||
83 | |||
84 | class GeneratedServiceStubType(GeneratedServiceType): | ||
85 | |||
86 | """Metaclass for service stubs created at runtime from ServiceDescriptors. | ||
87 | |||
88 | This class has similar responsibilities as GeneratedServiceType, except that | ||
89 | it creates the service stub classes. | ||
90 | """ | ||
91 | |||
92 | _DESCRIPTOR_KEY = 'DESCRIPTOR' | ||
93 | |||
94 | def __init__(cls, name, bases, dictionary): | ||
95 | """Creates a message service stub class. | ||
96 | |||
97 | Args: | ||
98 | name: Name of the class (ignored, here). | ||
99 | bases: Base classes of the class being constructed. | ||
100 | dictionary: The class dictionary of the class being constructed. | ||
101 | dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object | ||
102 | describing this protocol service type. | ||
103 | """ | ||
104 | super(GeneratedServiceStubType, cls).__init__(name, bases, dictionary) | ||
105 | # Don't do anything if this class doesn't have a descriptor. This happens | ||
106 | # when a service stub is subclassed. | ||
107 | if GeneratedServiceStubType._DESCRIPTOR_KEY not in dictionary: | ||
108 | return | ||
109 | descriptor = dictionary[GeneratedServiceStubType._DESCRIPTOR_KEY] | ||
110 | service_stub_builder = _ServiceStubBuilder(descriptor) | ||
111 | service_stub_builder.BuildServiceStub(cls) | ||
112 | |||
113 | |||
114 | class _ServiceBuilder(object): | ||
115 | |||
116 | """This class constructs a protocol service class using a service descriptor. | ||
117 | |||
118 | Given a service descriptor, this class constructs a class that represents | ||
119 | the specified service descriptor. One service builder instance constructs | ||
120 | exactly one service class. That means all instances of that class share the | ||
121 | same builder. | ||
122 | """ | ||
123 | |||
124 | def __init__(self, service_descriptor): | ||
125 | """Initializes an instance of the service class builder. | ||
126 | |||
127 | Args: | ||
128 | service_descriptor: ServiceDescriptor to use when constructing the | ||
129 | service class. | ||
130 | """ | ||
131 | self.descriptor = service_descriptor | ||
132 | |||
133 | def BuildService(self, cls): | ||
134 | """Constructs the service class. | ||
135 | |||
136 | Args: | ||
137 | cls: The class that will be constructed. | ||
138 | """ | ||
139 | |||
140 | # CallMethod needs to operate with an instance of the Service class. This | ||
141 | # internal wrapper function exists only to be able to pass the service | ||
142 | # instance to the method that does the real CallMethod work. | ||
143 | def _WrapCallMethod(srvc, method_descriptor, | ||
144 | rpc_controller, request, callback): | ||
145 | self._CallMethod(srvc, method_descriptor, | ||
146 | rpc_controller, request, callback) | ||
147 | self.cls = cls | ||
148 | cls.CallMethod = _WrapCallMethod | ||
149 | cls.GetDescriptor = self._GetDescriptor | ||
150 | cls.GetRequestClass = self._GetRequestClass | ||
151 | cls.GetResponseClass = self._GetResponseClass | ||
152 | for method in self.descriptor.methods: | ||
153 | setattr(cls, method.name, self._GenerateNonImplementedMethod(method)) | ||
154 | |||
155 | def _GetDescriptor(self): | ||
156 | """Retrieves the service descriptor. | ||
157 | |||
158 | Returns: | ||
159 | The descriptor of the service (of type ServiceDescriptor). | ||
160 | """ | ||
161 | return self.descriptor | ||
162 | |||
163 | def _CallMethod(self, srvc, method_descriptor, | ||
164 | rpc_controller, request, callback): | ||
165 | """Calls the method described by a given method descriptor. | ||
166 | |||
167 | Args: | ||
168 | srvc: Instance of the service for which this method is called. | ||
169 | method_descriptor: Descriptor that represent the method to call. | ||
170 | rpc_controller: RPC controller to use for this method's execution. | ||
171 | request: Request protocol message. | ||
172 | callback: A callback to invoke after the method has completed. | ||
173 | """ | ||
174 | if method_descriptor.containing_service != self.descriptor: | ||
175 | raise RuntimeError( | ||
176 | 'CallMethod() given method descriptor for wrong service type.') | ||
177 | method = getattr(srvc, method_descriptor.name) | ||
178 | method(rpc_controller, request, callback) | ||
179 | |||
180 | def _GetRequestClass(self, method_descriptor): | ||
181 | """Returns the class of the request protocol message. | ||
182 | |||
183 | Args: | ||
184 | method_descriptor: Descriptor of the method for which to return the | ||
185 | request protocol message class. | ||
186 | |||
187 | Returns: | ||
188 | A class that represents the input protocol message of the specified | ||
189 | method. | ||
190 | """ | ||
191 | if method_descriptor.containing_service != self.descriptor: | ||
192 | raise RuntimeError( | ||
193 | 'GetRequestClass() given method descriptor for wrong service type.') | ||
194 | return method_descriptor.input_type._concrete_class | ||
195 | |||
196 | def _GetResponseClass(self, method_descriptor): | ||
197 | """Returns the class of the response protocol message. | ||
198 | |||
199 | Args: | ||
200 | method_descriptor: Descriptor of the method for which to return the | ||
201 | response protocol message class. | ||
202 | |||
203 | Returns: | ||
204 | A class that represents the output protocol message of the specified | ||
205 | method. | ||
206 | """ | ||
207 | if method_descriptor.containing_service != self.descriptor: | ||
208 | raise RuntimeError( | ||
209 | 'GetResponseClass() given method descriptor for wrong service type.') | ||
210 | return method_descriptor.output_type._concrete_class | ||
211 | |||
212 | def _GenerateNonImplementedMethod(self, method): | ||
213 | """Generates and returns a method that can be set for a service methods. | ||
214 | |||
215 | Args: | ||
216 | method: Descriptor of the service method for which a method is to be | ||
217 | generated. | ||
218 | |||
219 | Returns: | ||
220 | A method that can be added to the service class. | ||
221 | """ | ||
222 | return lambda inst, rpc_controller, request, callback: ( | ||
223 | self._NonImplementedMethod(method.name, rpc_controller, callback)) | ||
224 | |||
225 | def _NonImplementedMethod(self, method_name, rpc_controller, callback): | ||
226 | """The body of all methods in the generated service class. | ||
227 | |||
228 | Args: | ||
229 | method_name: Name of the method being executed. | ||
230 | rpc_controller: RPC controller used to execute this method. | ||
231 | callback: A callback which will be invoked when the method finishes. | ||
232 | """ | ||
233 | rpc_controller.SetFailed('Method %s not implemented.' % method_name) | ||
234 | callback(None) | ||
235 | |||
236 | |||
237 | class _ServiceStubBuilder(object): | ||
238 | |||
239 | """Constructs a protocol service stub class using a service descriptor. | ||
240 | |||
241 | Given a service descriptor, this class constructs a suitable stub class. | ||
242 | A stub is just a type-safe wrapper around an RpcChannel which emulates a | ||
243 | local implementation of the service. | ||
244 | |||
245 | One service stub builder instance constructs exactly one class. It means all | ||
246 | instances of that class share the same service stub builder. | ||
247 | """ | ||
248 | |||
249 | def __init__(self, service_descriptor): | ||
250 | """Initializes an instance of the service stub class builder. | ||
251 | |||
252 | Args: | ||
253 | service_descriptor: ServiceDescriptor to use when constructing the | ||
254 | stub class. | ||
255 | """ | ||
256 | self.descriptor = service_descriptor | ||
257 | |||
258 | def BuildServiceStub(self, cls): | ||
259 | """Constructs the stub class. | ||
260 | |||
261 | Args: | ||
262 | cls: The class that will be constructed. | ||
263 | """ | ||
264 | |||
265 | def _ServiceStubInit(stub, rpc_channel): | ||
266 | stub.rpc_channel = rpc_channel | ||
267 | self.cls = cls | ||
268 | cls.__init__ = _ServiceStubInit | ||
269 | for method in self.descriptor.methods: | ||
270 | setattr(cls, method.name, self._GenerateStubMethod(method)) | ||
271 | |||
272 | def _GenerateStubMethod(self, method): | ||
273 | return lambda inst, rpc_controller, request, callback: self._StubMethod( | ||
274 | inst, method, rpc_controller, request, callback) | ||
275 | |||
276 | def _StubMethod(self, stub, method_descriptor, | ||
277 | rpc_controller, request, callback): | ||
278 | """The body of all service methods in the generated stub class. | ||
279 | |||
280 | Args: | ||
281 | stub: Stub instance. | ||
282 | method_descriptor: Descriptor of the invoked method. | ||
283 | rpc_controller: Rpc controller to execute the method. | ||
284 | request: Request protocol message. | ||
285 | callback: A callback to execute when the method finishes. | ||
286 | """ | ||
287 | stub.rpc_channel.CallMethod( | ||
288 | method_descriptor, rpc_controller, request, | ||
289 | method_descriptor.output_type._concrete_class, callback) | ||