blob: e4867e463a0ebfa7452c40021055257c13457ece [file] [log] [blame]
Joe Onoratoc596cfe2011-08-30 17:24:17 -07001#include "generate_java.h"
2#include "Type.h"
3#include <string.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7
Manuel Roman847c1e12011-10-06 10:28:35 -07008Type* SERVICE_CONTEXT_TYPE = new Type("android.content",
9 "Context", Type::BUILT_IN, false, false, false);
Joe Onorato76f479d2011-10-12 23:22:42 -070010Type* PRESENTER_BASE_TYPE = new Type("com.android.athome.connector",
11 "EventListener", Type::BUILT_IN, false, false, false);
12Type* PRESENTER_LISTENER_BASE_TYPE = new Type("com.android.athome.connector",
13 "EventListener.Listener", Type::BUILT_IN, false, false, false);
Joe Onoratod7f36582011-10-09 21:51:46 -070014Type* RPC_BROKER_TYPE = new Type("com.android.athome.connector", "Broker",
Joe Onoratoe20125d2011-09-23 15:17:52 -070015 Type::BUILT_IN, false, false, false);
Joe Onoratod7f36582011-10-09 21:51:46 -070016Type* RPC_CONTAINER_TYPE = new Type("com.android.athome.connector", "ConnectorContainer",
Joe Onoratoe20125d2011-09-23 15:17:52 -070017 Type::BUILT_IN, false, false, false);
Joe Onoratod7f36582011-10-09 21:51:46 -070018// TODO: Just use Endpoint, so this works for all endpoints.
19Type* RPC_CONNECTOR_TYPE = new Type("com.android.athome.connector", "Connector",
20 Type::BUILT_IN, false, false, false);
Joe Onoratobaaf9c82011-10-09 22:31:16 -070021Type* RPC_ENDPOINT_INFO_TYPE = new UserDataType("com.android.athome.rpc",
Joe Onoratod7f36582011-10-09 21:51:46 -070022 "EndpointInfo", true, __FILE__, __LINE__);
Joe Onoratobaaf9c82011-10-09 22:31:16 -070023Type* RPC_RESULT_HANDLER_TYPE = new UserDataType("com.android.athome.rpc", "RpcResultHandler",
Joe Onoratoe20125d2011-09-23 15:17:52 -070024 true, __FILE__, __LINE__);
25Type* RPC_ERROR_LISTENER_TYPE = new Type("com.android.athome.rpc", "RpcErrorHandler",
26 Type::BUILT_IN, false, false, false);
Joe Onoratobaaf9c82011-10-09 22:31:16 -070027Type* RPC_CONTEXT_TYPE = new UserDataType("com.android.athome.rpc", "RpcContext", true,
Manuel Roman847c1e12011-10-06 10:28:35 -070028 __FILE__, __LINE__);
Joe Onoratoe20125d2011-09-23 15:17:52 -070029
30static void generate_create_from_data(Type* t, StatementBlock* addTo, const string& key,
31 Variable* v, Variable* data, Variable** cl);
32static void generate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* from);
33static void generate_write_to_data(Type* t, StatementBlock* addTo, Expression* k, Variable* v,
34 Variable* data);
Joe Onoratoc596cfe2011-08-30 17:24:17 -070035
36static string
37format_int(int n)
38{
39 char str[20];
40 sprintf(str, "%d", n);
41 return string(str);
42}
43
44static string
45class_name_leaf(const string& str)
46{
47 string::size_type pos = str.rfind('.');
48 if (pos == string::npos) {
49 return str;
50 } else {
51 return string(str, pos+1);
52 }
53}
54
Joe Onoratoe20125d2011-09-23 15:17:52 -070055static string
56results_class_name(const string& n)
57{
58 string str = n;
59 str[0] = toupper(str[0]);
60 str.insert(0, "On");
61 return str;
62}
63
64static string
65results_method_name(const string& n)
66{
67 string str = n;
68 str[0] = toupper(str[0]);
69 str.insert(0, "on");
70 return str;
71}
72
73static string
74push_method_name(const string& n)
75{
76 string str = n;
77 str[0] = toupper(str[0]);
78 str.insert(0, "push");
79 return str;
80}
81
82// =================================================
83class DispatcherClass : public Class
84{
85public:
86 DispatcherClass(const interface_type* iface, Expression* target);
87 virtual ~DispatcherClass();
88
89 void AddMethod(const method_type* method);
90 void DoneWithMethods();
91
92 Method* processMethod;
93 Variable* actionParam;
94 Variable* requestParam;
Manuel Roman847c1e12011-10-06 10:28:35 -070095 Variable* rpcContextParam;
Joe Onoratoe20125d2011-09-23 15:17:52 -070096 Variable* errorParam;
97 Variable* requestData;
98 Variable* resultData;
99 IfStatement* dispatchIfStatement;
100 Expression* targetExpression;
101
102private:
103 void generate_process();
104};
105
106DispatcherClass::DispatcherClass(const interface_type* iface, Expression* target)
107 :Class(),
108 dispatchIfStatement(NULL),
109 targetExpression(target)
110{
111 generate_process();
112}
113
114DispatcherClass::~DispatcherClass()
115{
116}
117
118void
119DispatcherClass::generate_process()
120{
Manuel Roman847c1e12011-10-06 10:28:35 -0700121 // byte[] process(String action, byte[] params, RpcContext context, RpcError status)
Joe Onoratoe20125d2011-09-23 15:17:52 -0700122 this->processMethod = new Method;
123 this->processMethod->modifiers = PUBLIC;
124 this->processMethod->returnType = BYTE_TYPE;
125 this->processMethod->returnTypeDimension = 1;
126 this->processMethod->name = "process";
127 this->processMethod->statements = new StatementBlock;
128
129 this->actionParam = new Variable(STRING_TYPE, "action");
130 this->processMethod->parameters.push_back(this->actionParam);
131
132 this->requestParam = new Variable(BYTE_TYPE, "requestParam", 1);
133 this->processMethod->parameters.push_back(this->requestParam);
134
Manuel Roman847c1e12011-10-06 10:28:35 -0700135 this->rpcContextParam = new Variable(RPC_CONTEXT_TYPE, "context", 0);
136 this->processMethod->parameters.push_back(this->rpcContextParam);
137
Joe Onoratoe20125d2011-09-23 15:17:52 -0700138 this->errorParam = new Variable(RPC_ERROR_TYPE, "errorParam", 0);
139 this->processMethod->parameters.push_back(this->errorParam);
140
141 this->requestData = new Variable(RPC_DATA_TYPE, "request");
142 this->processMethod->statements->Add(new VariableDeclaration(requestData,
143 new NewExpression(RPC_DATA_TYPE, 1, this->requestParam)));
144
145 this->resultData = new Variable(RPC_DATA_TYPE, "resultData");
146 this->processMethod->statements->Add(new VariableDeclaration(this->resultData,
147 NULL_VALUE));
148}
149
150void
151DispatcherClass::AddMethod(const method_type* method)
152{
153 arg_type* arg;
154
155 // The if/switch statement
156 IfStatement* ifs = new IfStatement();
157 ifs->expression = new MethodCall(new StringLiteralExpression(method->name.data), "equals",
158 1, this->actionParam);
159 StatementBlock* block = ifs->statements = new StatementBlock;
160 if (this->dispatchIfStatement == NULL) {
161 this->dispatchIfStatement = ifs;
162 this->processMethod->statements->Add(dispatchIfStatement);
163 } else {
164 this->dispatchIfStatement->elseif = ifs;
165 this->dispatchIfStatement = ifs;
166 }
167
168 // The call to decl (from above)
169 MethodCall* realCall = new MethodCall(this->targetExpression, method->name.data);
170
171 // args
172 Variable* classLoader = NULL;
173 VariableFactory stubArgs("_arg");
174 arg = method->args;
175 while (arg != NULL) {
176 Type* t = NAMES.Search(arg->type.type.data);
177 Variable* v = stubArgs.Get(t);
178 v->dimension = arg->type.dimension;
179
180 // Unmarshall the parameter
181 block->Add(new VariableDeclaration(v));
182 if (convert_direction(arg->direction.data) & IN_PARAMETER) {
183 generate_create_from_data(t, block, arg->name.data, v,
184 this->requestData, &classLoader);
185 } else {
186 if (arg->type.dimension == 0) {
187 block->Add(new Assignment(v, new NewExpression(v->type)));
188 }
189 else if (arg->type.dimension == 1) {
190 generate_new_array(v->type, block, v, this->requestData);
191 }
192 else {
193 fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__,
194 __LINE__);
195 }
196 }
197
198 // Add that parameter to the method call
199 realCall->arguments.push_back(v);
200
201 arg = arg->next;
202 }
203
Manuel Roman847c1e12011-10-06 10:28:35 -0700204 // Add a final parameter: RpcContext. Contains data about
205 // incoming request (e.g., certificate)
206 realCall->arguments.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
Joe Onoratoe20125d2011-09-23 15:17:52 -0700207
208 Type* returnType = NAMES.Search(method->type.type.data);
209 if (returnType == EVENT_FAKE_TYPE) {
210 returnType = VOID_TYPE;
211 }
212
213 // the real call
214 bool first = true;
215 Variable* _result = NULL;
216 if (returnType == VOID_TYPE) {
217 block->Add(realCall);
218 } else {
219 _result = new Variable(returnType, "_result",
220 method->type.dimension);
221 block->Add(new VariableDeclaration(_result, realCall));
222
223 // need the result RpcData
224 if (first) {
225 block->Add(new Assignment(this->resultData,
226 new NewExpression(RPC_DATA_TYPE)));
227 first = false;
228 }
229
230 // marshall the return value
231 generate_write_to_data(returnType, block,
232 new StringLiteralExpression("_result"), _result, this->resultData);
233 }
234
235 // out parameters
236 int i = 0;
237 arg = method->args;
238 while (arg != NULL) {
239 Type* t = NAMES.Search(arg->type.type.data);
240 Variable* v = stubArgs.Get(i++);
241
242 if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
243 // need the result RpcData
244 if (first) {
245 block->Add(new Assignment(this->resultData, new NewExpression(RPC_DATA_TYPE)));
246 first = false;
247 }
248
249 generate_write_to_data(t, block, new StringLiteralExpression(arg->name.data),
250 v, this->resultData);
251 }
252
253 arg = arg->next;
254 }
255}
256
257void
258DispatcherClass::DoneWithMethods()
259{
260 if (this->dispatchIfStatement == NULL) {
261 return;
262 }
263
264 this->elements.push_back(this->processMethod);
265
266 IfStatement* fallthrough = new IfStatement();
267 fallthrough->statements = new StatementBlock;
268 fallthrough->statements->Add(new ReturnStatement(
Manuel Roman847c1e12011-10-06 10:28:35 -0700269 new MethodCall(SUPER_VALUE, "process", 4,
270 this->actionParam, this->requestParam,
271 this->rpcContextParam,
272 this->errorParam)));
Joe Onoratoe20125d2011-09-23 15:17:52 -0700273 this->dispatchIfStatement->elseif = fallthrough;
274 IfStatement* s = new IfStatement;
275 s->statements = new StatementBlock;
276 this->processMethod->statements->Add(s);
277 s->expression = new Comparison(this->resultData, "!=", NULL_VALUE);
278 s->statements->Add(new ReturnStatement(new MethodCall(this->resultData, "serialize")));
279 s->elseif = new IfStatement;
280 s = s->elseif;
281 s->statements->Add(new ReturnStatement(NULL_VALUE));
282}
283
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700284// =================================================
285class RpcProxyClass : public Class
286{
287public:
288 RpcProxyClass(const interface_type* iface, InterfaceType* interfaceType);
289 virtual ~RpcProxyClass();
290
291 Variable* endpoint;
Joe Onoratod7f36582011-10-09 21:51:46 -0700292 Variable* broker;
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700293
294private:
295 void generate_ctor();
296};
297
298RpcProxyClass::RpcProxyClass(const interface_type* iface, InterfaceType* interfaceType)
299 :Class()
300{
301 this->comment = gather_comments(iface->comments_token->extra);
302 this->modifiers = PUBLIC;
303 this->what = Class::CLASS;
304 this->type = interfaceType;
305
Joe Onoratod7f36582011-10-09 21:51:46 -0700306 // broker
307 this->broker = new Variable(RPC_BROKER_TYPE, "_broker");
308 this->elements.push_back(new Field(PRIVATE, this->broker));
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700309 // endpoint
Joe Onoratod7f36582011-10-09 21:51:46 -0700310 this->endpoint = new Variable(RPC_ENDPOINT_INFO_TYPE, "_endpoint");
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700311 this->elements.push_back(new Field(PRIVATE, this->endpoint));
312
313 // methods
314 generate_ctor();
315}
316
317RpcProxyClass::~RpcProxyClass()
318{
319}
320
321void
322RpcProxyClass::generate_ctor()
323{
Joe Onoratod7f36582011-10-09 21:51:46 -0700324 Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
325 Variable* endpoint = new Variable(RPC_ENDPOINT_INFO_TYPE, "endpoint");
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700326 Method* ctor = new Method;
327 ctor->modifiers = PUBLIC;
Joe Onoratoe20125d2011-09-23 15:17:52 -0700328 ctor->name = class_name_leaf(this->type->Name());
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700329 ctor->statements = new StatementBlock;
Joe Onoratod7f36582011-10-09 21:51:46 -0700330 ctor->parameters.push_back(broker);
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700331 ctor->parameters.push_back(endpoint);
332 this->elements.push_back(ctor);
333
Joe Onoratod7f36582011-10-09 21:51:46 -0700334 ctor->statements->Add(new Assignment(this->broker, broker));
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700335 ctor->statements->Add(new Assignment(this->endpoint, endpoint));
336}
337
338// =================================================
Joe Onorato76f479d2011-10-12 23:22:42 -0700339class EventListenerClass : public DispatcherClass
Joe Onoratoe20125d2011-09-23 15:17:52 -0700340{
341public:
Joe Onorato76f479d2011-10-12 23:22:42 -0700342 EventListenerClass(const interface_type* iface, Type* listenerType);
343 virtual ~EventListenerClass();
Joe Onoratoe20125d2011-09-23 15:17:52 -0700344
345 Variable* _listener;
346
347private:
348 void generate_ctor();
349};
350
351Expression*
352generate_get_listener_expression(Type* cast)
353{
354 return new Cast(cast, new MethodCall(THIS_VALUE, "getView"));
355}
356
Joe Onorato76f479d2011-10-12 23:22:42 -0700357EventListenerClass::EventListenerClass(const interface_type* iface, Type* listenerType)
358 :DispatcherClass(iface, new FieldVariable(THIS_VALUE, "_listener"))
Joe Onoratoe20125d2011-09-23 15:17:52 -0700359{
360 this->modifiers = PRIVATE;
361 this->what = Class::CLASS;
362 this->type = new Type(iface->package ? iface->package : "",
363 append(iface->name.data, ".Presenter"),
364 Type::GENERATED, false, false, false);
365 this->extends = PRESENTER_BASE_TYPE;
366
367 this->_listener = new Variable(listenerType, "_listener");
Tim Kilbournd88e12e2011-09-27 10:30:53 -0700368 this->elements.push_back(new Field(PRIVATE, this->_listener));
Joe Onoratoe20125d2011-09-23 15:17:52 -0700369
370 // methods
371 generate_ctor();
372}
373
Joe Onorato76f479d2011-10-12 23:22:42 -0700374EventListenerClass::~EventListenerClass()
Joe Onoratoe20125d2011-09-23 15:17:52 -0700375{
376}
377
378void
Joe Onorato76f479d2011-10-12 23:22:42 -0700379EventListenerClass::generate_ctor()
Joe Onoratoe20125d2011-09-23 15:17:52 -0700380{
Joe Onoratod7f36582011-10-09 21:51:46 -0700381 Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
Joe Onoratoe20125d2011-09-23 15:17:52 -0700382 Variable* listener = new Variable(this->_listener->type, "listener");
383 Method* ctor = new Method;
384 ctor->modifiers = PUBLIC;
385 ctor->name = class_name_leaf(this->type->Name());
386 ctor->statements = new StatementBlock;
Joe Onoratod7f36582011-10-09 21:51:46 -0700387 ctor->parameters.push_back(broker);
Joe Onoratoe20125d2011-09-23 15:17:52 -0700388 ctor->parameters.push_back(listener);
389 this->elements.push_back(ctor);
390
Joe Onorato76f479d2011-10-12 23:22:42 -0700391 ctor->statements->Add(new MethodCall("super", 2, broker, listener));
Joe Onoratoe20125d2011-09-23 15:17:52 -0700392 ctor->statements->Add(new Assignment(this->_listener, listener));
393}
394
395// =================================================
396class ListenerClass : public Class
397{
398public:
399 ListenerClass(const interface_type* iface);
400 virtual ~ListenerClass();
401
402 bool needed;
403
404private:
405 void generate_ctor();
406};
407
408ListenerClass::ListenerClass(const interface_type* iface)
409 :Class(),
410 needed(false)
411{
412 this->comment = "/** Extend this to listen to the events from this class. */";
413 this->modifiers = STATIC | PUBLIC ;
414 this->what = Class::CLASS;
415 this->type = new Type(iface->package ? iface->package : "",
416 append(iface->name.data, ".Listener"),
417 Type::GENERATED, false, false, false);
418 this->extends = PRESENTER_LISTENER_BASE_TYPE;
419}
420
421ListenerClass::~ListenerClass()
422{
423}
424
425// =================================================
Joe Onoratod7f36582011-10-09 21:51:46 -0700426class EndpointBaseClass : public DispatcherClass
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700427{
428public:
Joe Onoratod7f36582011-10-09 21:51:46 -0700429 EndpointBaseClass(const interface_type* iface);
430 virtual ~EndpointBaseClass();
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700431
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700432 bool needed;
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700433
434private:
435 void generate_ctor();
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700436};
437
Joe Onoratod7f36582011-10-09 21:51:46 -0700438EndpointBaseClass::EndpointBaseClass(const interface_type* iface)
Joe Onoratoe20125d2011-09-23 15:17:52 -0700439 :DispatcherClass(iface, THIS_VALUE),
440 needed(false)
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700441{
442 this->comment = "/** Extend this to implement a link service. */";
443 this->modifiers = STATIC | PUBLIC | ABSTRACT;
444 this->what = Class::CLASS;
Joe Onoratoe20125d2011-09-23 15:17:52 -0700445 this->type = new Type(iface->package ? iface->package : "",
Joe Onoratod7f36582011-10-09 21:51:46 -0700446 append(iface->name.data, ".EndpointBase"),
Joe Onoratoe20125d2011-09-23 15:17:52 -0700447 Type::GENERATED, false, false, false);
Joe Onoratod7f36582011-10-09 21:51:46 -0700448 this->extends = RPC_CONNECTOR_TYPE;
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700449
450 // methods
451 generate_ctor();
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700452}
453
Joe Onoratod7f36582011-10-09 21:51:46 -0700454EndpointBaseClass::~EndpointBaseClass()
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700455{
456}
457
458void
Joe Onoratod7f36582011-10-09 21:51:46 -0700459EndpointBaseClass::generate_ctor()
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700460{
Joe Onoratod7f36582011-10-09 21:51:46 -0700461 Variable* container = new Variable(RPC_CONTAINER_TYPE, "container");
462 Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700463 Method* ctor = new Method;
464 ctor->modifiers = PUBLIC;
465 ctor->name = class_name_leaf(this->type->Name());
466 ctor->statements = new StatementBlock;
Joe Onoratod7f36582011-10-09 21:51:46 -0700467 ctor->parameters.push_back(container);
468 ctor->parameters.push_back(broker);
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700469 this->elements.push_back(ctor);
470
Joe Onoratod7f36582011-10-09 21:51:46 -0700471 ctor->statements->Add(new MethodCall("super", 2, container, broker));
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700472}
473
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700474// =================================================
475class ResultDispatcherClass : public Class
476{
477public:
478 ResultDispatcherClass();
479 virtual ~ResultDispatcherClass();
480
481 void AddMethod(int index, const string& name, Method** method, Variable** param);
482
483 bool needed;
484 Variable* methodId;
485 Variable* callback;
486 Method* onResultMethod;
487 Variable* resultParam;
488 SwitchStatement* methodSwitch;
489
490private:
491 void generate_ctor();
492 void generate_onResult();
493};
494
495ResultDispatcherClass::ResultDispatcherClass()
496 :Class(),
497 needed(false)
498{
499 this->modifiers = PRIVATE | FINAL;
500 this->what = Class::CLASS;
Joe Onorato4135a7d2011-09-15 21:31:15 -0700501 this->type = new Type("_ResultDispatcher", Type::GENERATED, false, false, false);
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700502 this->interfaces.push_back(RPC_RESULT_HANDLER_TYPE);
503
504 // methodId
505 this->methodId = new Variable(INT_TYPE, "methodId");
506 this->elements.push_back(new Field(PRIVATE, this->methodId));
507 this->callback = new Variable(OBJECT_TYPE, "callback");
508 this->elements.push_back(new Field(PRIVATE, this->callback));
509
510 // methods
511 generate_ctor();
512 generate_onResult();
513}
514
515ResultDispatcherClass::~ResultDispatcherClass()
516{
517}
518
519void
520ResultDispatcherClass::generate_ctor()
521{
522 Variable* methodIdParam = new Variable(INT_TYPE, "methId");
523 Variable* callbackParam = new Variable(OBJECT_TYPE, "cbObj");
524 Method* ctor = new Method;
525 ctor->modifiers = PUBLIC;
Joe Onoratoe20125d2011-09-23 15:17:52 -0700526 ctor->name = class_name_leaf(this->type->Name());
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700527 ctor->statements = new StatementBlock;
528 ctor->parameters.push_back(methodIdParam);
529 ctor->parameters.push_back(callbackParam);
530 this->elements.push_back(ctor);
531
532 ctor->statements->Add(new Assignment(this->methodId, methodIdParam));
533 ctor->statements->Add(new Assignment(this->callback, callbackParam));
534}
535
536void
537ResultDispatcherClass::generate_onResult()
538{
539 this->onResultMethod = new Method;
540 this->onResultMethod->modifiers = PUBLIC;
541 this->onResultMethod->returnType = VOID_TYPE;
542 this->onResultMethod->returnTypeDimension = 0;
543 this->onResultMethod->name = "onResult";
544 this->onResultMethod->statements = new StatementBlock;
545 this->elements.push_back(this->onResultMethod);
546
547 this->resultParam = new Variable(BYTE_TYPE, "result", 1);
548 this->onResultMethod->parameters.push_back(this->resultParam);
549
550 this->methodSwitch = new SwitchStatement(this->methodId);
551 this->onResultMethod->statements->Add(this->methodSwitch);
552}
553
554void
555ResultDispatcherClass::AddMethod(int index, const string& name, Method** method, Variable** param)
556{
557 Method* m = new Method;
558 m->modifiers = PUBLIC;
559 m->returnType = VOID_TYPE;
560 m->returnTypeDimension = 0;
561 m->name = name;
562 m->statements = new StatementBlock;
563 *param = new Variable(BYTE_TYPE, "result", 1);
564 m->parameters.push_back(*param);
565 this->elements.push_back(m);
566 *method = m;
567
568 Case* c = new Case(format_int(index));
569 c->statements->Add(new MethodCall(new LiteralExpression("this"), name, 1, this->resultParam));
Joe Onorato3d0e06f2011-09-02 15:28:36 -0700570 c->statements->Add(new Break());
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700571
572 this->methodSwitch->cases.push_back(c);
573}
574
575// =================================================
576static void
577generate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* from)
578{
579 fprintf(stderr, "aidl: implement generate_new_array %s:%d\n", __FILE__, __LINE__);
580 exit(1);
581}
582
583static void
584generate_create_from_data(Type* t, StatementBlock* addTo, const string& key, Variable* v,
585 Variable* data, Variable** cl)
586{
587 Expression* k = new StringLiteralExpression(key);
588 if (v->dimension == 0) {
589 t->CreateFromRpcData(addTo, k, v, data, cl);
590 }
591 if (v->dimension == 1) {
592 //t->ReadArrayFromRpcData(addTo, v, data, cl);
593 fprintf(stderr, "aidl: implement generate_create_from_data for arrays%s:%d\n",
594 __FILE__, __LINE__);
595 }
596}
597
598static void
599generate_write_to_data(Type* t, StatementBlock* addTo, Expression* k, Variable* v, Variable* data)
600{
601 if (v->dimension == 0) {
602 t->WriteToRpcData(addTo, k, v, data, 0);
603 }
604 if (v->dimension == 1) {
605 //t->WriteArrayToParcel(addTo, v, data);
606 fprintf(stderr, "aidl: implement generate_write_to_data for arrays%s:%d\n",
607 __FILE__, __LINE__);
608 }
609}
610
611// =================================================
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700612static Type*
613generate_results_method(const method_type* method, RpcProxyClass* proxyClass)
614{
615 arg_type* arg;
616
617 string resultsMethodName = results_method_name(method->name.data);
618 Type* resultsInterfaceType = new Type(results_class_name(method->name.data),
Joe Onorato4135a7d2011-09-15 21:31:15 -0700619 Type::GENERATED, false, false, false);
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700620
621 if (!method->oneway) {
622 Class* resultsClass = new Class;
623 resultsClass->modifiers = STATIC | PUBLIC;
624 resultsClass->what = Class::INTERFACE;
625 resultsClass->type = resultsInterfaceType;
626
627 Method* resultMethod = new Method;
628 resultMethod->comment = gather_comments(method->comments_token->extra);
629 resultMethod->modifiers = PUBLIC;
630 resultMethod->returnType = VOID_TYPE;
631 resultMethod->returnTypeDimension = 0;
632 resultMethod->name = resultsMethodName;
633 if (0 != strcmp("void", method->type.type.data)) {
634 resultMethod->parameters.push_back(new Variable(NAMES.Search(method->type.type.data),
635 "_result", method->type.dimension));
636 }
637 arg = method->args;
638 while (arg != NULL) {
639 if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
640 resultMethod->parameters.push_back(new Variable(
641 NAMES.Search(arg->type.type.data), arg->name.data,
642 arg->type.dimension));
643 }
644 arg = arg->next;
645 }
646 resultsClass->elements.push_back(resultMethod);
647
648 if (resultMethod->parameters.size() > 0) {
649 proxyClass->elements.push_back(resultsClass);
650 return resultsInterfaceType;
651 }
652 }
653 //delete resultsInterfaceType;
654 return NULL;
655}
656
657static void
658generate_proxy_method(const method_type* method, RpcProxyClass* proxyClass,
659 ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index)
660{
661 arg_type* arg;
662 Method* proxyMethod = new Method;
663 proxyMethod->comment = gather_comments(method->comments_token->extra);
664 proxyMethod->modifiers = PUBLIC;
665 proxyMethod->returnType = VOID_TYPE;
666 proxyMethod->returnTypeDimension = 0;
667 proxyMethod->name = method->name.data;
668 proxyMethod->statements = new StatementBlock;
669 proxyClass->elements.push_back(proxyMethod);
670
671 // The local variables
672 Variable* _data = new Variable(RPC_DATA_TYPE, "_data");
673 proxyMethod->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE)));
674
675 // Add the arguments
676 arg = method->args;
677 while (arg != NULL) {
678 if (convert_direction(arg->direction.data) & IN_PARAMETER) {
679 // Function signature
680 Type* t = NAMES.Search(arg->type.type.data);
681 Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
682 proxyMethod->parameters.push_back(v);
683
684 // Input parameter marshalling
685 generate_write_to_data(t, proxyMethod->statements,
686 new StringLiteralExpression(arg->name.data), v, _data);
687 }
688 arg = arg->next;
689 }
690
691 // If there is a results interface for this class
692 Expression* resultParameter;
693 if (resultsInterfaceType != NULL) {
694 // Result interface parameter
695 Variable* resultListener = new Variable(resultsInterfaceType, "_result");
696 proxyMethod->parameters.push_back(resultListener);
697
698 // Add the results dispatcher callback
699 resultsDispatcherClass->needed = true;
700 resultParameter = new NewExpression(resultsDispatcherClass->type, 2,
701 new LiteralExpression(format_int(index)), resultListener);
702 } else {
703 resultParameter = NULL_VALUE;
704 }
705
706 // All proxy methods take an error parameter
707 Variable* errorListener = new Variable(RPC_ERROR_LISTENER_TYPE, "_errors");
708 proxyMethod->parameters.push_back(errorListener);
709
710 // Call the broker
Joe Onoratod7f36582011-10-09 21:51:46 -0700711 proxyMethod->statements->Add(new MethodCall(new FieldVariable(THIS_VALUE, "_broker"),
712 "sendRpc", 5,
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700713 proxyClass->endpoint,
Joe Onoratod7f36582011-10-09 21:51:46 -0700714 new StringLiteralExpression(method->name.data),
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700715 new MethodCall(_data, "serialize"),
716 resultParameter,
717 errorListener));
718}
719
720static void
721generate_result_dispatcher_method(const method_type* method,
722 ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index)
723{
724 arg_type* arg;
725 Method* dispatchMethod;
726 Variable* dispatchParam;
727 resultsDispatcherClass->AddMethod(index, method->name.data, &dispatchMethod, &dispatchParam);
728
729 Variable* classLoader = NULL;
730 Variable* resultData = new Variable(RPC_DATA_TYPE, "resultData");
731 dispatchMethod->statements->Add(new VariableDeclaration(resultData,
732 new NewExpression(RPC_DATA_TYPE, 1, dispatchParam)));
733
734 // The callback method itself
735 MethodCall* realCall = new MethodCall(
736 new Cast(resultsInterfaceType, new FieldVariable(THIS_VALUE, "callback")),
737 results_method_name(method->name.data));
738
739 // The return value
740 {
741 Type* t = NAMES.Search(method->type.type.data);
742 Variable* rv = new Variable(t, "rv");
743 dispatchMethod->statements->Add(new VariableDeclaration(rv));
744 generate_create_from_data(t, dispatchMethod->statements, "_result", rv,
745 resultData, &classLoader);
746 realCall->arguments.push_back(rv);
747 }
748
749 VariableFactory stubArgs("arg");
750 arg = method->args;
751 while (arg != NULL) {
752 if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
753 // Unmarshall the results
754 Type* t = NAMES.Search(arg->type.type.data);
755 Variable* v = stubArgs.Get(t);
756 dispatchMethod->statements->Add(new VariableDeclaration(v));
757
758 generate_create_from_data(t, dispatchMethod->statements, arg->name.data, v,
759 resultData, &classLoader);
760
761 // Add the argument to the callback
762 realCall->arguments.push_back(v);
763 }
764 arg = arg->next;
765 }
766
767 // Call the callback method
768 dispatchMethod->statements->Add(realCall);
769}
770
771static void
Joe Onoratoe20125d2011-09-23 15:17:52 -0700772generate_regular_method(const method_type* method, RpcProxyClass* proxyClass,
Joe Onoratod7f36582011-10-09 21:51:46 -0700773 EndpointBaseClass* serviceBaseClass, ResultDispatcherClass* resultsDispatcherClass,
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700774 int index)
775{
Joe Onoratoe20125d2011-09-23 15:17:52 -0700776 arg_type* arg;
777
778 // == the callback interface for results ================================
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700779 // the service base class
780 Type* resultsInterfaceType = generate_results_method(method, proxyClass);
781
782 // == the method in the proxy class =====================================
783 generate_proxy_method(method, proxyClass, resultsDispatcherClass, resultsInterfaceType, index);
784
785 // == the method in the result dispatcher class =========================
786 if (resultsInterfaceType != NULL) {
787 generate_result_dispatcher_method(method, resultsDispatcherClass, resultsInterfaceType,
788 index);
789 }
790
Joe Onoratoe20125d2011-09-23 15:17:52 -0700791 // == The abstract method that the service developers implement ==========
792 Method* decl = new Method;
793 decl->comment = gather_comments(method->comments_token->extra);
794 decl->modifiers = PUBLIC | ABSTRACT;
795 decl->returnType = NAMES.Search(method->type.type.data);
796 decl->returnTypeDimension = method->type.dimension;
797 decl->name = method->name.data;
798 arg = method->args;
799 while (arg != NULL) {
800 decl->parameters.push_back(new Variable(
801 NAMES.Search(arg->type.type.data), arg->name.data,
802 arg->type.dimension));
803 arg = arg->next;
804 }
Manuel Roman847c1e12011-10-06 10:28:35 -0700805
806 // Add the default RpcContext param to all methods
807 decl->parameters.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
808
Joe Onoratoe20125d2011-09-23 15:17:52 -0700809 serviceBaseClass->elements.push_back(decl);
810
811
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700812 // == the dispatch method in the service base class ======================
Joe Onoratoe20125d2011-09-23 15:17:52 -0700813 serviceBaseClass->AddMethod(method);
814}
815
816static void
817generate_event_method(const method_type* method, RpcProxyClass* proxyClass,
Joe Onoratod7f36582011-10-09 21:51:46 -0700818 EndpointBaseClass* serviceBaseClass, ListenerClass* listenerClass,
Joe Onorato76f479d2011-10-12 23:22:42 -0700819 EventListenerClass* presenterClass, int index)
Joe Onoratoe20125d2011-09-23 15:17:52 -0700820{
821 arg_type* arg;
822 listenerClass->needed = true;
823
824 // == the push method in the service base class =========================
825 Method* push = new Method;
826 push->modifiers = PUBLIC;
827 push->name = push_method_name(method->name.data);
828 push->statements = new StatementBlock;
829 push->returnType = VOID_TYPE;
830 serviceBaseClass->elements.push_back(push);
831
832 // The local variables
833 Variable* _data = new Variable(RPC_DATA_TYPE, "_data");
834 push->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE)));
835
836 // Add the arguments
837 arg = method->args;
838 while (arg != NULL) {
839 // Function signature
840 Type* t = NAMES.Search(arg->type.type.data);
841 Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
842 push->parameters.push_back(v);
843
844 // Input parameter marshalling
845 generate_write_to_data(t, push->statements,
846 new StringLiteralExpression(arg->name.data), v, _data);
847
848 arg = arg->next;
849 }
850
851 // Send the notifications
852 push->statements->Add(new MethodCall("pushEvent", 2,
853 new StringLiteralExpression(method->name.data),
854 new MethodCall(_data, "serialize")));
855
856 // == the event callback dispatcher method ====================================
857 presenterClass->AddMethod(method);
858
859 // == the event method in the listener base class =====================
860 Method* event = new Method;
861 event->modifiers = PUBLIC;
862 event->name = method->name.data;
863 event->statements = new StatementBlock;
864 event->returnType = VOID_TYPE;
865 listenerClass->elements.push_back(event);
866 arg = method->args;
867 while (arg != NULL) {
868 event->parameters.push_back(new Variable(
869 NAMES.Search(arg->type.type.data), arg->name.data,
870 arg->type.dimension));
871 arg = arg->next;
872 }
Manuel Roman847c1e12011-10-06 10:28:35 -0700873
874 // Add a final parameter: RpcContext. Contains data about
875 // incoming request (e.g., certificate)
876 event->parameters.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
Joe Onoratoe20125d2011-09-23 15:17:52 -0700877}
878
879static void
880generate_listener_methods(RpcProxyClass* proxyClass, Type* presenterType, Type* listenerType)
881{
882 // AndroidAtHomePresenter _presenter;
Joe Onorato76f479d2011-10-12 23:22:42 -0700883 // void startListening(Listener listener) {
884 // stopListening();
885 // _presenter = new Presenter(_broker, listener);
886 // _presenter.startListening(_endpoint);
Joe Onoratoe20125d2011-09-23 15:17:52 -0700887 // }
Joe Onorato76f479d2011-10-12 23:22:42 -0700888 // void stopListening() {
Joe Onoratoe20125d2011-09-23 15:17:52 -0700889 // if (_presenter != null) {
Joe Onorato76f479d2011-10-12 23:22:42 -0700890 // _presenter.stopListening();
Joe Onoratoe20125d2011-09-23 15:17:52 -0700891 // }
892 // }
893
894 Variable* _presenter = new Variable(presenterType, "_presenter");
895 proxyClass->elements.push_back(new Field(PRIVATE, _presenter));
896
897 Variable* listener = new Variable(listenerType, "listener");
898
Joe Onorato76f479d2011-10-12 23:22:42 -0700899 Method* startListeningMethod = new Method;
900 startListeningMethod->modifiers = PUBLIC;
901 startListeningMethod->returnType = VOID_TYPE;
902 startListeningMethod->name = "startListening";
903 startListeningMethod->statements = new StatementBlock;
904 startListeningMethod->parameters.push_back(listener);
905 proxyClass->elements.push_back(startListeningMethod);
Joe Onoratoe20125d2011-09-23 15:17:52 -0700906
Joe Onorato76f479d2011-10-12 23:22:42 -0700907 startListeningMethod->statements->Add(new MethodCall(THIS_VALUE, "stopListening"));
908 startListeningMethod->statements->Add(new Assignment(_presenter,
909 new NewExpression(presenterType, 2, proxyClass->broker, listener)));
910 startListeningMethod->statements->Add(new MethodCall(_presenter,
911 "startListening", 1, proxyClass->endpoint));
Joe Onoratoe20125d2011-09-23 15:17:52 -0700912
Joe Onorato76f479d2011-10-12 23:22:42 -0700913 Method* stopListeningMethod = new Method;
914 stopListeningMethod->modifiers = PUBLIC;
915 stopListeningMethod->returnType = VOID_TYPE;
916 stopListeningMethod->name = "stopListening";
917 stopListeningMethod->statements = new StatementBlock;
918 proxyClass->elements.push_back(stopListeningMethod);
Joe Onoratoe20125d2011-09-23 15:17:52 -0700919
920 IfStatement* ifst = new IfStatement;
921 ifst->expression = new Comparison(_presenter, "!=", NULL_VALUE);
Joe Onorato76f479d2011-10-12 23:22:42 -0700922 stopListeningMethod->statements->Add(ifst);
Joe Onoratoe20125d2011-09-23 15:17:52 -0700923
Joe Onorato76f479d2011-10-12 23:22:42 -0700924 ifst->statements->Add(new MethodCall(_presenter, "stopListening"));
Joe Onoratoe20125d2011-09-23 15:17:52 -0700925 ifst->statements->Add(new Assignment(_presenter, NULL_VALUE));
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700926}
927
928Class*
929generate_rpc_interface_class(const interface_type* iface)
930{
931 // the proxy class
932 InterfaceType* interfaceType = static_cast<InterfaceType*>(
933 NAMES.Find(iface->package, iface->name.data));
934 RpcProxyClass* proxy = new RpcProxyClass(iface, interfaceType);
935
Joe Onoratoe20125d2011-09-23 15:17:52 -0700936 // the listener class
937 ListenerClass* listener = new ListenerClass(iface);
938
939 // the presenter class
Joe Onorato76f479d2011-10-12 23:22:42 -0700940 EventListenerClass* presenter = new EventListenerClass(iface, listener->type);
Joe Onoratoe20125d2011-09-23 15:17:52 -0700941
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700942 // the service base class
Joe Onoratod7f36582011-10-09 21:51:46 -0700943 EndpointBaseClass* base = new EndpointBaseClass(iface);
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700944 proxy->elements.push_back(base);
945
946 // the result dispatcher
947 ResultDispatcherClass* results = new ResultDispatcherClass();
948
949 // all the declared methods of the proxy
950 int index = 0;
951 interface_item_type* item = iface->interface_items;
952 while (item != NULL) {
953 if (item->item_type == METHOD_TYPE) {
Joe Onoratoe20125d2011-09-23 15:17:52 -0700954 if (NAMES.Search(((method_type*)item)->type.type.data) == EVENT_FAKE_TYPE) {
955 generate_event_method((method_type*)item, proxy, base, listener, presenter, index);
956 } else {
957 generate_regular_method((method_type*)item, proxy, base, results, index);
958 }
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700959 }
960 item = item->next;
961 index++;
962 }
Joe Onoratoe20125d2011-09-23 15:17:52 -0700963 presenter->DoneWithMethods();
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700964 base->DoneWithMethods();
965
966 // only add this if there are methods with results / out parameters
967 if (results->needed) {
968 proxy->elements.push_back(results);
969 }
Joe Onoratoe20125d2011-09-23 15:17:52 -0700970 if (listener->needed) {
971 proxy->elements.push_back(listener);
972 proxy->elements.push_back(presenter);
973 generate_listener_methods(proxy, presenter->type, listener->type);
974 }
Joe Onoratoc596cfe2011-08-30 17:24:17 -0700975
976 return proxy;
977}