31 """Contains metaclasses used to create protocol service and service stub
32 classes from ServiceDescriptor objects at runtime.
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.
39 __author__ =
'petar@google.com (Petar Petrov)'
42 class GeneratedServiceType(
type):
44 """Metaclass for service classes created at runtime from ServiceDescriptors.
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.
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::
54 mydescriptor = ServiceDescriptor(.....)
55 class MyProtoService(service.Service):
56 __metaclass__ = GeneratedServiceType
57 DESCRIPTOR = mydescriptor
58 myservice_instance = MyProtoService()
62 _DESCRIPTOR_KEY =
'DESCRIPTOR'
65 """Creates a message service class.
68 name: Name of the class (ignored, but required by the metaclass
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.
77 if GeneratedServiceType._DESCRIPTOR_KEY
not in dictionary:
80 descriptor = dictionary[GeneratedServiceType._DESCRIPTOR_KEY]
82 service_builder.BuildService(cls)
88 """Metaclass for service stubs created at runtime from ServiceDescriptors.
90 This class has similar responsibilities as GeneratedServiceType, except that
91 it creates the service stub classes.
94 _DESCRIPTOR_KEY =
'DESCRIPTOR'
97 """Creates a message service stub class.
100 name: Name of the class (ignored, here).
101 bases: Base classes of the class being constructed.
102 dictionary: The class dictionary of the class being constructed.
103 dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object
104 describing this protocol service type.
106 super(GeneratedServiceStubType, cls).
__init__(name, bases, dictionary)
109 if GeneratedServiceStubType._DESCRIPTOR_KEY
not in dictionary:
112 descriptor = dictionary[GeneratedServiceStubType._DESCRIPTOR_KEY]
114 service_stub_builder.BuildServiceStub(cls)
119 """This class constructs a protocol service class using a service descriptor.
121 Given a service descriptor, this class constructs a class that represents
122 the specified service descriptor. One service builder instance constructs
123 exactly one service class. That means all instances of that class share the
128 """Initializes an instance of the service class builder.
131 service_descriptor: ServiceDescriptor to use when constructing the
137 """Constructs the service class.
140 cls: The class that will be constructed.
146 def _WrapCallMethod(srvc, method_descriptor,
147 rpc_controller, request, callback):
149 rpc_controller, request, callback)
153 cls.
GetDescriptor.__doc__ =
"Returns the service descriptor."
160 rpc_controller, request, callback):
161 """Calls the method described by a given method descriptor.
164 srvc: Instance of the service for which this method is called.
165 method_descriptor: Descriptor that represent the method to call.
166 rpc_controller: RPC controller to use for this method's execution.
167 request: Request protocol message.
168 callback: A callback to invoke after the method has completed.
170 if method_descriptor.containing_service != self.
descriptor:
172 'CallMethod() given method descriptor for wrong service type.')
173 method = getattr(srvc, method_descriptor.name)
174 return method(rpc_controller, request, callback)
177 """Returns the class of the request protocol message.
180 method_descriptor: Descriptor of the method for which to return the
181 request protocol message class.
184 A class that represents the input protocol message of the specified
187 if method_descriptor.containing_service != self.
descriptor:
189 'GetRequestClass() given method descriptor for wrong service type.')
190 return method_descriptor.input_type._concrete_class
193 """Returns the class of the response protocol message.
196 method_descriptor: Descriptor of the method for which to return the
197 response protocol message class.
200 A class that represents the output protocol message of the specified
203 if method_descriptor.containing_service != self.
descriptor:
205 'GetResponseClass() given method descriptor for wrong service type.')
206 return method_descriptor.output_type._concrete_class
209 """Generates and returns a method that can be set for a service methods.
212 method: Descriptor of the service method for which a method is to be
216 A method that can be added to the service class.
218 return lambda inst, rpc_controller, request, callback: (
222 """The body of all methods in the generated service class.
225 method_name: Name of the method being executed.
226 rpc_controller: RPC controller used to execute this method.
227 callback: A callback which will be invoked when the method finishes.
229 rpc_controller.SetFailed(
'Method %s not implemented.' % method_name)
235 """Constructs a protocol service stub class using a service descriptor.
237 Given a service descriptor, this class constructs a suitable stub class.
238 A stub is just a type-safe wrapper around an RpcChannel which emulates a
239 local implementation of the service.
241 One service stub builder instance constructs exactly one class. It means all
242 instances of that class share the same service stub builder.
246 """Initializes an instance of the service stub class builder.
249 service_descriptor: ServiceDescriptor to use when constructing the
255 """Constructs the stub class.
258 cls: The class that will be constructed.
261 def _ServiceStubInit(stub, rpc_channel):
262 stub.rpc_channel = rpc_channel
269 return (
lambda inst, rpc_controller, request, callback=
None:
270 self.
_StubMethod(inst, method, rpc_controller, request, callback))
273 rpc_controller, request, callback):
274 """The body of all service methods in the generated stub class.
278 method_descriptor: Descriptor of the invoked method.
279 rpc_controller: Rpc controller to execute the method.
280 request: Request protocol message.
281 callback: A callback to execute when the method finishes.
283 Response message (in case of blocking call).
285 return stub.rpc_channel.CallMethod(
286 method_descriptor, rpc_controller, request,
287 method_descriptor.output_type._concrete_class, callback)