generate_java_rpc.cpp revision 9d98a089756b692eefeae7f92cca15e121196e0c
17add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato#include "generate_java.h"
27add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato#include "Type.h"
37add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato#include <string.h>
47add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato#include <stdio.h>
57add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato#include <stdlib.h>
67add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato#include <string.h>
77add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
89a7822497fa38539fdf9dacc6860c436e2925251Joe OnoratoType* ANDROID_CONTEXT_TYPE = new Type("android.content",
92c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman        "Context", Type::BUILT_IN, false, false, false);
100c86196fe1c4ede51249ebb439ecd31ecd2acbd1Joe OnoratoType* PRESENTER_BASE_TYPE = new Type("android.support.place.connector",
11c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato        "EventListener", Type::BUILT_IN, false, false, false);
120c86196fe1c4ede51249ebb439ecd31ecd2acbd1Joe OnoratoType* PRESENTER_LISTENER_BASE_TYPE = new Type("android.support.place.connector",
13c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato        "EventListener.Listener", Type::BUILT_IN, false, false, false);
140c86196fe1c4ede51249ebb439ecd31ecd2acbd1Joe OnoratoType* RPC_BROKER_TYPE = new Type("android.support.place.connector", "Broker",
15e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        Type::BUILT_IN, false, false, false);
16a8744b7cdf2463c7e412cf49ba6cfcad799c4acaManuel RomanType* PLACE_INFO_TYPE = new Type("android.support.place.connector", "PlaceInfo",
17a8744b7cdf2463c7e412cf49ba6cfcad799c4acaManuel Roman        Type::BUILT_IN, false, false, false);
180d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato// TODO: Just use Endpoint, so this works for all endpoints.
190c86196fe1c4ede51249ebb439ecd31ecd2acbd1Joe OnoratoType* RPC_CONNECTOR_TYPE = new Type("android.support.place.connector", "Connector",
200d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato        Type::BUILT_IN, false, false, false);
210c86196fe1c4ede51249ebb439ecd31ecd2acbd1Joe OnoratoType* RPC_ENDPOINT_INFO_TYPE = new UserDataType("android.support.place.rpc",
220d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato        "EndpointInfo", true, __FILE__, __LINE__);
230c86196fe1c4ede51249ebb439ecd31ecd2acbd1Joe OnoratoType* RPC_RESULT_HANDLER_TYPE = new UserDataType("android.support.place.rpc", "RpcResultHandler",
24e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        true, __FILE__, __LINE__);
250c86196fe1c4ede51249ebb439ecd31ecd2acbd1Joe OnoratoType* RPC_ERROR_LISTENER_TYPE = new Type("android.support.place.rpc", "RpcErrorHandler",
26e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        Type::BUILT_IN, false, false, false);
270c86196fe1c4ede51249ebb439ecd31ecd2acbd1Joe OnoratoType* RPC_CONTEXT_TYPE = new UserDataType("android.support.place.rpc", "RpcContext", true,
282c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman        __FILE__, __LINE__);
29e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
30e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratostatic void generate_create_from_data(Type* t, StatementBlock* addTo, const string& key,
31e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        Variable* v, Variable* data, Variable** cl);
32e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratostatic void generate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* from);
33e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratostatic void generate_write_to_data(Type* t, StatementBlock* addTo, Expression* k, Variable* v,
34e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        Variable* data);
357add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
367add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratostatic string
377add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratoformat_int(int n)
387add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
397add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    char str[20];
407add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    sprintf(str, "%d", n);
417add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    return string(str);
427add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
437add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
447add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratostatic string
457add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratoclass_name_leaf(const string& str)
467add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
477add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    string::size_type pos = str.rfind('.');
487add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    if (pos == string::npos) {
497add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        return str;
507add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    } else {
517add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        return string(str, pos+1);
527add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
537add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
547add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
55e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratostatic string
56e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratoresults_class_name(const string& n)
57e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
58e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    string str = n;
59e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    str[0] = toupper(str[0]);
60e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    str.insert(0, "On");
61e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    return str;
62e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
63e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
64e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratostatic string
65e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratoresults_method_name(const string& n)
66e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
67e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    string str = n;
68e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    str[0] = toupper(str[0]);
69e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    str.insert(0, "on");
70e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    return str;
71e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
72e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
73e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratostatic string
74e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratopush_method_name(const string& n)
75e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
76e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    string str = n;
77e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    str[0] = toupper(str[0]);
78e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    str.insert(0, "push");
79e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    return str;
80e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
81e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
82e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato// =================================================
83e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratoclass DispatcherClass : public Class
84e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
85e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratopublic:
86e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    DispatcherClass(const interface_type* iface, Expression* target);
87e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    virtual ~DispatcherClass();
88e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
89e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    void AddMethod(const method_type* method);
90e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    void DoneWithMethods();
91e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
92e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Method* processMethod;
93e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Variable* actionParam;
94e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Variable* requestParam;
952c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman    Variable* rpcContextParam;
96e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Variable* errorParam;
97e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Variable* requestData;
98e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Variable* resultData;
99e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    IfStatement* dispatchIfStatement;
100e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Expression* targetExpression;
101e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
102e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratoprivate:
103e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    void generate_process();
104e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato};
105e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
106e415ecb47952879665b08aacf40988f518f8bda3Joe OnoratoDispatcherClass::DispatcherClass(const interface_type* iface, Expression* target)
107e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    :Class(),
108e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato     dispatchIfStatement(NULL),
109e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato     targetExpression(target)
110e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
111e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    generate_process();
112e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
113e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
114e415ecb47952879665b08aacf40988f518f8bda3Joe OnoratoDispatcherClass::~DispatcherClass()
115e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
116e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
117e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
118e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratovoid
119e415ecb47952879665b08aacf40988f518f8bda3Joe OnoratoDispatcherClass::generate_process()
120e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
1212c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman    // byte[] process(String action, byte[] params, RpcContext context, RpcError status)
122e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->processMethod = new Method;
123e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        this->processMethod->modifiers = PUBLIC;
124e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        this->processMethod->returnType = BYTE_TYPE;
125e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        this->processMethod->returnTypeDimension = 1;
126e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        this->processMethod->name = "process";
127e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        this->processMethod->statements = new StatementBlock;
128e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
129e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->actionParam = new Variable(STRING_TYPE, "action");
130e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->processMethod->parameters.push_back(this->actionParam);
131e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
132e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->requestParam = new Variable(BYTE_TYPE, "requestParam", 1);
133e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->processMethod->parameters.push_back(this->requestParam);
134e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
1352c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman    this->rpcContextParam = new Variable(RPC_CONTEXT_TYPE, "context", 0);
1362c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman    this->processMethod->parameters.push_back(this->rpcContextParam);
1372c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman
138e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->errorParam = new Variable(RPC_ERROR_TYPE, "errorParam", 0);
139e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->processMethod->parameters.push_back(this->errorParam);
140e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
141e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->requestData = new Variable(RPC_DATA_TYPE, "request");
142e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->processMethod->statements->Add(new VariableDeclaration(requestData,
143e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                new NewExpression(RPC_DATA_TYPE, 1, this->requestParam)));
144e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
145e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->resultData = new Variable(RPC_DATA_TYPE, "resultData");
146e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->processMethod->statements->Add(new VariableDeclaration(this->resultData,
147e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                NULL_VALUE));
148e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
149e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
150e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratovoid
151e415ecb47952879665b08aacf40988f518f8bda3Joe OnoratoDispatcherClass::AddMethod(const method_type* method)
152e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
153e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    arg_type* arg;
154e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
155e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // The if/switch statement
156e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    IfStatement* ifs = new IfStatement();
157e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        ifs->expression = new MethodCall(new StringLiteralExpression(method->name.data), "equals",
158e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                1, this->actionParam);
159e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    StatementBlock* block = ifs->statements = new StatementBlock;
160e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    if (this->dispatchIfStatement == NULL) {
161e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        this->dispatchIfStatement = ifs;
162e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        this->processMethod->statements->Add(dispatchIfStatement);
163e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    } else {
164e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        this->dispatchIfStatement->elseif = ifs;
165e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        this->dispatchIfStatement = ifs;
166e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    }
167e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
168e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // The call to decl (from above)
169e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    MethodCall* realCall = new MethodCall(this->targetExpression, method->name.data);
170e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
171e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // args
172e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Variable* classLoader = NULL;
173e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    VariableFactory stubArgs("_arg");
174e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    arg = method->args;
175e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    while (arg != NULL) {
176e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        Type* t = NAMES.Search(arg->type.type.data);
177e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        Variable* v = stubArgs.Get(t);
178e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        v->dimension = arg->type.dimension;
179e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
180e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        // Unmarshall the parameter
181e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        block->Add(new VariableDeclaration(v));
182e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        if (convert_direction(arg->direction.data) & IN_PARAMETER) {
183e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            generate_create_from_data(t, block, arg->name.data, v,
184e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                    this->requestData, &classLoader);
185e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        } else {
186e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            if (arg->type.dimension == 0) {
187e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                block->Add(new Assignment(v, new NewExpression(v->type)));
188e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            }
189e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            else if (arg->type.dimension == 1) {
190e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                generate_new_array(v->type, block, v, this->requestData);
191e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            }
192e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            else {
193e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__,
194e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                        __LINE__);
195e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            }
196e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        }
197e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
198e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        // Add that parameter to the method call
199e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        realCall->arguments.push_back(v);
200e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
201e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        arg = arg->next;
202e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    }
203e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
2042c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman    // Add a final parameter: RpcContext. Contains data about
2052c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman    // incoming request (e.g., certificate)
2062c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman    realCall->arguments.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
207e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
208e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Type* returnType = NAMES.Search(method->type.type.data);
209e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    if (returnType == EVENT_FAKE_TYPE) {
210e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        returnType = VOID_TYPE;
211e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    }
212e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
213e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // the real call
214e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    bool first = true;
215e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Variable* _result = NULL;
216e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    if (returnType == VOID_TYPE) {
217e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        block->Add(realCall);
218e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    } else {
219e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        _result = new Variable(returnType, "_result",
220e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                                method->type.dimension);
221e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        block->Add(new VariableDeclaration(_result, realCall));
222e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
223e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        // need the result RpcData
224e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        if (first) {
225e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            block->Add(new Assignment(this->resultData,
226e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                        new NewExpression(RPC_DATA_TYPE)));
227e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            first = false;
228e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        }
229e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
230e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        // marshall the return value
231e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        generate_write_to_data(returnType, block,
232e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                new StringLiteralExpression("_result"), _result, this->resultData);
233e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    }
234e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
235e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // out parameters
236e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    int i = 0;
237e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    arg = method->args;
238e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    while (arg != NULL) {
239e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        Type* t = NAMES.Search(arg->type.type.data);
240e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        Variable* v = stubArgs.Get(i++);
241e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
242e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
243e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            // need the result RpcData
244e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            if (first) {
245e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                block->Add(new Assignment(this->resultData, new NewExpression(RPC_DATA_TYPE)));
246e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                first = false;
247e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            }
248e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
249e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            generate_write_to_data(t, block, new StringLiteralExpression(arg->name.data),
250e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                    v, this->resultData);
251e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        }
252e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
253e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        arg = arg->next;
254e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    }
255e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
256e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
257e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratovoid
258e415ecb47952879665b08aacf40988f518f8bda3Joe OnoratoDispatcherClass::DoneWithMethods()
259e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
260e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    if (this->dispatchIfStatement == NULL) {
261e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        return;
262e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    }
263e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
264e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->elements.push_back(this->processMethod);
265e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
266e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    IfStatement* fallthrough = new IfStatement();
267e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        fallthrough->statements = new StatementBlock;
268e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        fallthrough->statements->Add(new ReturnStatement(
2692c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman                    new MethodCall(SUPER_VALUE, "process", 4,
2702c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman                    this->actionParam, this->requestParam,
2712c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman                    this->rpcContextParam,
2722c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman                    this->errorParam)));
273e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->dispatchIfStatement->elseif = fallthrough;
274e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    IfStatement* s = new IfStatement;
275e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        s->statements = new StatementBlock;
276e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->processMethod->statements->Add(s);
277e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    s->expression = new Comparison(this->resultData, "!=", NULL_VALUE);
278e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    s->statements->Add(new ReturnStatement(new MethodCall(this->resultData, "serialize")));
279e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    s->elseif = new IfStatement;
280e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    s = s->elseif;
281e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    s->statements->Add(new ReturnStatement(NULL_VALUE));
282e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
283e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
2847add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato// =================================================
2857add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratoclass RpcProxyClass : public Class
2867add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
2877add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratopublic:
2887add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    RpcProxyClass(const interface_type* iface, InterfaceType* interfaceType);
2897add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    virtual ~RpcProxyClass();
2907add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
2917add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Variable* endpoint;
2920d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    Variable* broker;
2937add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
2947add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratoprivate:
2957add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    void generate_ctor();
29620e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons    void generate_get_endpoint_info();
2977add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato};
2987add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
2997add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe OnoratoRpcProxyClass::RpcProxyClass(const interface_type* iface, InterfaceType* interfaceType)
3007add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    :Class()
3017add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
3027add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->comment = gather_comments(iface->comments_token->extra);
3037add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->modifiers = PUBLIC;
3047add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->what = Class::CLASS;
3057add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->type = interfaceType;
3067add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
3070d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    // broker
3080d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    this->broker = new Variable(RPC_BROKER_TYPE, "_broker");
3090d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    this->elements.push_back(new Field(PRIVATE, this->broker));
3107add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // endpoint
3110d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    this->endpoint = new Variable(RPC_ENDPOINT_INFO_TYPE, "_endpoint");
3127add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->elements.push_back(new Field(PRIVATE, this->endpoint));
3137add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
3147add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // methods
3157add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    generate_ctor();
31620e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons    generate_get_endpoint_info();
3177add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
3187add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
3197add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe OnoratoRpcProxyClass::~RpcProxyClass()
3207add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
3217add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
3227add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
3237add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratovoid
3247add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe OnoratoRpcProxyClass::generate_ctor()
3257add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
3260d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
3270d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    Variable* endpoint = new Variable(RPC_ENDPOINT_INFO_TYPE, "endpoint");
3287add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Method* ctor = new Method;
3297add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        ctor->modifiers = PUBLIC;
330e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        ctor->name = class_name_leaf(this->type->Name());
3317add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        ctor->statements = new StatementBlock;
3320d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato        ctor->parameters.push_back(broker);
3337add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        ctor->parameters.push_back(endpoint);
3347add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->elements.push_back(ctor);
3357add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
3360d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    ctor->statements->Add(new Assignment(this->broker, broker));
3377add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    ctor->statements->Add(new Assignment(this->endpoint, endpoint));
3387add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
3397add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
34020e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmonsvoid
34120e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason SimmonsRpcProxyClass::generate_get_endpoint_info()
34220e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons{
34320e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons    Method* get = new Method;
34420e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons    get->modifiers = PUBLIC;
34520e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons    get->returnType = RPC_ENDPOINT_INFO_TYPE;
34620e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons    get->name = "getEndpointInfo";
34720e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons    get->statements = new StatementBlock;
34820e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons    this->elements.push_back(get);
34920e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons
35020e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons    get->statements->Add(new ReturnStatement(this->endpoint));
35120e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons}
35220e0cef180397d9d98a51f1a6b8f14d6d4e83ab2Jason Simmons
3537add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato// =================================================
354c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onoratoclass EventListenerClass : public DispatcherClass
355e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
356e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratopublic:
357c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    EventListenerClass(const interface_type* iface, Type* listenerType);
358c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    virtual ~EventListenerClass();
359e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
360e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Variable* _listener;
361e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
362e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratoprivate:
363e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    void generate_ctor();
364e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato};
365e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
366e415ecb47952879665b08aacf40988f518f8bda3Joe OnoratoExpression*
367e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratogenerate_get_listener_expression(Type* cast)
368e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
369e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    return new Cast(cast, new MethodCall(THIS_VALUE, "getView"));
370e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
371e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
372c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe OnoratoEventListenerClass::EventListenerClass(const interface_type* iface, Type* listenerType)
373c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    :DispatcherClass(iface, new FieldVariable(THIS_VALUE, "_listener"))
374e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
375e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->modifiers = PRIVATE;
376e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->what = Class::CLASS;
377e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->type = new Type(iface->package ? iface->package : "",
378e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                        append(iface->name.data, ".Presenter"),
379e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                        Type::GENERATED, false, false, false);
380e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->extends = PRESENTER_BASE_TYPE;
381e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
382e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->_listener = new Variable(listenerType, "_listener");
383b8a6f22e1b2b73b7ca4570ed3ce94ccea6b1c9ceTim Kilbourn    this->elements.push_back(new Field(PRIVATE, this->_listener));
384e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
385e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // methods
386e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    generate_ctor();
387e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
388e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
389c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe OnoratoEventListenerClass::~EventListenerClass()
390e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
391e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
392e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
393e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratovoid
394c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe OnoratoEventListenerClass::generate_ctor()
395e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
3960d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
397e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Variable* listener = new Variable(this->_listener->type, "listener");
398e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Method* ctor = new Method;
399e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        ctor->modifiers = PUBLIC;
400e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        ctor->name = class_name_leaf(this->type->Name());
401e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        ctor->statements = new StatementBlock;
4020d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato        ctor->parameters.push_back(broker);
403e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        ctor->parameters.push_back(listener);
404e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->elements.push_back(ctor);
405e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
406c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    ctor->statements->Add(new MethodCall("super", 2, broker, listener));
407e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    ctor->statements->Add(new Assignment(this->_listener, listener));
408e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
409e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
410e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato// =================================================
411e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratoclass ListenerClass : public Class
412e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
413e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratopublic:
414e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    ListenerClass(const interface_type* iface);
415e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    virtual ~ListenerClass();
416e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
417e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    bool needed;
418e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
419e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratoprivate:
420e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    void generate_ctor();
421e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato};
422e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
423e415ecb47952879665b08aacf40988f518f8bda3Joe OnoratoListenerClass::ListenerClass(const interface_type* iface)
424e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    :Class(),
425e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato     needed(false)
426e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
427e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->comment = "/** Extend this to listen to the events from this class. */";
428e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->modifiers = STATIC | PUBLIC ;
429e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->what = Class::CLASS;
430e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->type = new Type(iface->package ? iface->package : "",
431e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                        append(iface->name.data, ".Listener"),
432e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                        Type::GENERATED, false, false, false);
433e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->extends = PRESENTER_LISTENER_BASE_TYPE;
434e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
435e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
436e415ecb47952879665b08aacf40988f518f8bda3Joe OnoratoListenerClass::~ListenerClass()
437e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
438e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
439e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
440e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato// =================================================
4410d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onoratoclass EndpointBaseClass : public DispatcherClass
4427add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
4437add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratopublic:
4440d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    EndpointBaseClass(const interface_type* iface);
4450d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    virtual ~EndpointBaseClass();
4467add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
4477add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    bool needed;
4487add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
4497add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratoprivate:
4507add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    void generate_ctor();
4517add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato};
4527add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
4530d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe OnoratoEndpointBaseClass::EndpointBaseClass(const interface_type* iface)
454e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    :DispatcherClass(iface, THIS_VALUE),
455e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato     needed(false)
4567add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
4577add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->comment = "/** Extend this to implement a link service. */";
4587add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->modifiers = STATIC | PUBLIC | ABSTRACT;
4597add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->what = Class::CLASS;
460e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    this->type = new Type(iface->package ? iface->package : "",
4610d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato                        append(iface->name.data, ".EndpointBase"),
462e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                        Type::GENERATED, false, false, false);
4630d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    this->extends = RPC_CONNECTOR_TYPE;
4647add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
4657add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // methods
4667add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    generate_ctor();
4677add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
4687add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
4690d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe OnoratoEndpointBaseClass::~EndpointBaseClass()
4707add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
4717add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
4727add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
4737add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratovoid
4740d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe OnoratoEndpointBaseClass::generate_ctor()
4757add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
4769a7822497fa38539fdf9dacc6860c436e2925251Joe Onorato    Variable* container = new Variable(ANDROID_CONTEXT_TYPE, "context");
4770d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    Variable* broker = new Variable(RPC_BROKER_TYPE, "broker");
478a8744b7cdf2463c7e412cf49ba6cfcad799c4acaManuel Roman	Variable* place = new Variable(PLACE_INFO_TYPE, "placeInfo");
4797add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Method* ctor = new Method;
4807add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        ctor->modifiers = PUBLIC;
4817add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        ctor->name = class_name_leaf(this->type->Name());
4827add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        ctor->statements = new StatementBlock;
4830d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato        ctor->parameters.push_back(container);
4840d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato        ctor->parameters.push_back(broker);
485a8744b7cdf2463c7e412cf49ba6cfcad799c4acaManuel Roman        ctor->parameters.push_back(place);
4867add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->elements.push_back(ctor);
4877add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
488a8744b7cdf2463c7e412cf49ba6cfcad799c4acaManuel Roman    ctor->statements->Add(new MethodCall("super", 3, container, broker, place));
4897add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
4907add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
4917add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato// =================================================
4927add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratoclass ResultDispatcherClass : public Class
4937add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
4947add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratopublic:
4957add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    ResultDispatcherClass();
4967add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    virtual ~ResultDispatcherClass();
4977add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
4987add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    void AddMethod(int index, const string& name, Method** method, Variable** param);
4997add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5007add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    bool needed;
5017add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Variable* methodId;
5027add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Variable* callback;
5037add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Method* onResultMethod;
5047add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Variable* resultParam;
5057add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    SwitchStatement* methodSwitch;
5067add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5077add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratoprivate:
5087add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    void generate_ctor();
5097add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    void generate_onResult();
5107add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato};
5117add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5127add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe OnoratoResultDispatcherClass::ResultDispatcherClass()
5137add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    :Class(),
5147add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato     needed(false)
5157add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
5167add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->modifiers = PRIVATE | FINAL;
5177add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->what = Class::CLASS;
5180ca2a36d8dd783e7ba5abffd5929c0e33c6ba91dJoe Onorato    this->type = new Type("_ResultDispatcher", Type::GENERATED, false, false, false);
5197add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->interfaces.push_back(RPC_RESULT_HANDLER_TYPE);
5207add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5217add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // methodId
5227add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->methodId = new Variable(INT_TYPE, "methodId");
5237add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->elements.push_back(new Field(PRIVATE, this->methodId));
5247add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->callback = new Variable(OBJECT_TYPE, "callback");
5257add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->elements.push_back(new Field(PRIVATE, this->callback));
5267add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5277add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // methods
5287add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    generate_ctor();
5297add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    generate_onResult();
5307add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
5317add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5327add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe OnoratoResultDispatcherClass::~ResultDispatcherClass()
5337add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
5347add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
5357add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5367add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratovoid
5377add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe OnoratoResultDispatcherClass::generate_ctor()
5387add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
5397add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Variable* methodIdParam = new Variable(INT_TYPE, "methId");
5407add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Variable* callbackParam = new Variable(OBJECT_TYPE, "cbObj");
5417add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Method* ctor = new Method;
5427add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        ctor->modifiers = PUBLIC;
543e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        ctor->name = class_name_leaf(this->type->Name());
5447add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        ctor->statements = new StatementBlock;
5457add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        ctor->parameters.push_back(methodIdParam);
5467add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        ctor->parameters.push_back(callbackParam);
5477add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->elements.push_back(ctor);
5487add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5497add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    ctor->statements->Add(new Assignment(this->methodId, methodIdParam));
5507add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    ctor->statements->Add(new Assignment(this->callback, callbackParam));
5517add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
5527add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5537add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratovoid
5547add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe OnoratoResultDispatcherClass::generate_onResult()
5557add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
5567add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->onResultMethod = new Method;
5577add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        this->onResultMethod->modifiers = PUBLIC;
5587add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        this->onResultMethod->returnType = VOID_TYPE;
5597add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        this->onResultMethod->returnTypeDimension = 0;
5607add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        this->onResultMethod->name = "onResult";
5617add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        this->onResultMethod->statements = new StatementBlock;
5627add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->elements.push_back(this->onResultMethod);
5637add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5647add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->resultParam = new Variable(BYTE_TYPE, "result", 1);
5657add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->onResultMethod->parameters.push_back(this->resultParam);
5667add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5677add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->methodSwitch = new SwitchStatement(this->methodId);
5687add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->onResultMethod->statements->Add(this->methodSwitch);
5697add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
5707add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5717add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratovoid
5727add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe OnoratoResultDispatcherClass::AddMethod(int index, const string& name, Method** method, Variable** param)
5737add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
5747add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Method* m = new Method;
5757add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        m->modifiers = PUBLIC;
5767add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        m->returnType = VOID_TYPE;
5777add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        m->returnTypeDimension = 0;
5787add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        m->name = name;
5797add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        m->statements = new StatementBlock;
5807add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    *param = new Variable(BYTE_TYPE, "result", 1);
5817add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    m->parameters.push_back(*param);
5827add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->elements.push_back(m);
5837add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    *method = m;
5847add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5857add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Case* c = new Case(format_int(index));
5867add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    c->statements->Add(new MethodCall(new LiteralExpression("this"), name, 1, this->resultParam));
587a1426e61f4004ed8744f81366d15c209fa7cf9b7Joe Onorato    c->statements->Add(new Break());
5887add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5897add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    this->methodSwitch->cases.push_back(c);
5907add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
5917add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
5927add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato// =================================================
5937add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratostatic void
5947add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratogenerate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* from)
5957add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
5967add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    fprintf(stderr, "aidl: implement generate_new_array %s:%d\n", __FILE__, __LINE__);
5977add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    exit(1);
5987add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
5997add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
6007add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratostatic void
6017add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratogenerate_create_from_data(Type* t, StatementBlock* addTo, const string& key, Variable* v,
6027add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                            Variable* data, Variable** cl)
6037add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
6047add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Expression* k = new StringLiteralExpression(key);
6057add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    if (v->dimension == 0) {
6067add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        t->CreateFromRpcData(addTo, k, v, data, cl);
6077add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
6087add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    if (v->dimension == 1) {
6097add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        //t->ReadArrayFromRpcData(addTo, v, data, cl);
6107add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        fprintf(stderr, "aidl: implement generate_create_from_data for arrays%s:%d\n",
6117add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                __FILE__, __LINE__);
6127add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
6137add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
6147add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
6157add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratostatic void
6167add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratogenerate_write_to_data(Type* t, StatementBlock* addTo, Expression* k, Variable* v, Variable* data)
6177add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
6187add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    if (v->dimension == 0) {
6197add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        t->WriteToRpcData(addTo, k, v, data, 0);
6207add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
6217add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    if (v->dimension == 1) {
6227add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        //t->WriteArrayToParcel(addTo, v, data);
6237add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        fprintf(stderr, "aidl: implement generate_write_to_data for arrays%s:%d\n",
6247add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                __FILE__, __LINE__);
6257add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
6267add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
6277add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
6287add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato// =================================================
6297add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratostatic Type*
6307add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratogenerate_results_method(const method_type* method, RpcProxyClass* proxyClass)
6317add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
6327add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    arg_type* arg;
6337add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
6347add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    string resultsMethodName = results_method_name(method->name.data);
6357add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Type* resultsInterfaceType = new Type(results_class_name(method->name.data),
6360ca2a36d8dd783e7ba5abffd5929c0e33c6ba91dJoe Onorato            Type::GENERATED, false, false, false);
6377add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
6387add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    if (!method->oneway) {
6397add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        Class* resultsClass = new Class;
6407add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            resultsClass->modifiers = STATIC | PUBLIC;
6417add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            resultsClass->what = Class::INTERFACE;
6427add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            resultsClass->type = resultsInterfaceType;
6437add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
6447add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        Method* resultMethod = new Method;
6457add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            resultMethod->comment = gather_comments(method->comments_token->extra);
6467add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            resultMethod->modifiers = PUBLIC;
6477add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            resultMethod->returnType = VOID_TYPE;
6487add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            resultMethod->returnTypeDimension = 0;
6497add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            resultMethod->name = resultsMethodName;
6507add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        if (0 != strcmp("void", method->type.type.data)) {
6517add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            resultMethod->parameters.push_back(new Variable(NAMES.Search(method->type.type.data),
6527add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                        "_result", method->type.dimension));
6537add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        }
6547add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        arg = method->args;
6557add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        while (arg != NULL) {
6567add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
6577add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                resultMethod->parameters.push_back(new Variable(
6587add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                                    NAMES.Search(arg->type.type.data), arg->name.data,
6597add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                                    arg->type.dimension));
6607add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            }
6617add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            arg = arg->next;
6627add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        }
6637add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        resultsClass->elements.push_back(resultMethod);
6647add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
6657add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        if (resultMethod->parameters.size() > 0) {
6667add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            proxyClass->elements.push_back(resultsClass);
6677add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            return resultsInterfaceType;
6687add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        }
6697add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
6707add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    //delete resultsInterfaceType;
6717add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    return NULL;
6727add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
6737add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
6747add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratostatic void
6757add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratogenerate_proxy_method(const method_type* method, RpcProxyClass* proxyClass,
6767add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index)
6777add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
6787add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    arg_type* arg;
6797add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Method* proxyMethod = new Method;
6807add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        proxyMethod->comment = gather_comments(method->comments_token->extra);
6817add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        proxyMethod->modifiers = PUBLIC;
6827add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        proxyMethod->returnType = VOID_TYPE;
6837add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        proxyMethod->returnTypeDimension = 0;
6847add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        proxyMethod->name = method->name.data;
6857add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        proxyMethod->statements = new StatementBlock;
6867add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    proxyClass->elements.push_back(proxyMethod);
6877add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
6887add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // The local variables
6897add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Variable* _data = new Variable(RPC_DATA_TYPE, "_data");
6907add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    proxyMethod->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE)));
6917add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
6927add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // Add the arguments
6937add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    arg = method->args;
6947add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    while (arg != NULL) {
6957add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        if (convert_direction(arg->direction.data) & IN_PARAMETER) {
6967add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            // Function signature
6977add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            Type* t = NAMES.Search(arg->type.type.data);
6987add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
6997add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            proxyMethod->parameters.push_back(v);
7007add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7017add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            // Input parameter marshalling
7027add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            generate_write_to_data(t, proxyMethod->statements,
7037add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                    new StringLiteralExpression(arg->name.data), v, _data);
7047add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        }
7057add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        arg = arg->next;
7067add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
7077add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7087add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // If there is a results interface for this class
7097add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Expression* resultParameter;
7107add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    if (resultsInterfaceType != NULL) {
7117add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        // Result interface parameter
7127add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        Variable* resultListener = new Variable(resultsInterfaceType, "_result");
7137add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        proxyMethod->parameters.push_back(resultListener);
7147add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7157add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        // Add the results dispatcher callback
7167add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        resultsDispatcherClass->needed = true;
7177add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        resultParameter = new NewExpression(resultsDispatcherClass->type, 2,
7187add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                new LiteralExpression(format_int(index)), resultListener);
7197add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    } else {
7207add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        resultParameter = NULL_VALUE;
7217add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
7227add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7237add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // All proxy methods take an error parameter
7247add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Variable* errorListener = new Variable(RPC_ERROR_LISTENER_TYPE, "_errors");
7257add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    proxyMethod->parameters.push_back(errorListener);
7267add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7277add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // Call the broker
7280d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    proxyMethod->statements->Add(new MethodCall(new FieldVariable(THIS_VALUE, "_broker"),
7290d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato                "sendRpc", 5,
7307add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                proxyClass->endpoint,
7310d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato                new StringLiteralExpression(method->name.data),
7327add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                new MethodCall(_data, "serialize"),
7337add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                resultParameter,
7347add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                errorListener));
7357add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
7367add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7377add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratostatic void
7387add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratogenerate_result_dispatcher_method(const method_type* method,
7397add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index)
7407add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
7417add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    arg_type* arg;
7427add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Method* dispatchMethod;
7437add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Variable* dispatchParam;
7447add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    resultsDispatcherClass->AddMethod(index, method->name.data, &dispatchMethod, &dispatchParam);
7457add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7467add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Variable* classLoader = NULL;
7477add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Variable* resultData = new Variable(RPC_DATA_TYPE, "resultData");
7487add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    dispatchMethod->statements->Add(new VariableDeclaration(resultData,
7497add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                new NewExpression(RPC_DATA_TYPE, 1, dispatchParam)));
7507add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7517add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // The callback method itself
7527add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    MethodCall* realCall = new MethodCall(
7537add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            new Cast(resultsInterfaceType, new FieldVariable(THIS_VALUE, "callback")),
7547add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            results_method_name(method->name.data));
7557add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7567add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // The return value
7577add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    {
7587add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        Type* t = NAMES.Search(method->type.type.data);
7596980de4ef9a67ed6227eecf5b059a8d2e3d470d2Joe Onorato        if (t != VOID_TYPE) {
7606980de4ef9a67ed6227eecf5b059a8d2e3d470d2Joe Onorato            Variable* rv = new Variable(t, "rv");
7616980de4ef9a67ed6227eecf5b059a8d2e3d470d2Joe Onorato            dispatchMethod->statements->Add(new VariableDeclaration(rv));
7626980de4ef9a67ed6227eecf5b059a8d2e3d470d2Joe Onorato            generate_create_from_data(t, dispatchMethod->statements, "_result", rv,
7636980de4ef9a67ed6227eecf5b059a8d2e3d470d2Joe Onorato                    resultData, &classLoader);
7646980de4ef9a67ed6227eecf5b059a8d2e3d470d2Joe Onorato            realCall->arguments.push_back(rv);
7656980de4ef9a67ed6227eecf5b059a8d2e3d470d2Joe Onorato        }
7667add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
7677add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7687add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    VariableFactory stubArgs("arg");
7697add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    arg = method->args;
7707add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    while (arg != NULL) {
7717add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
7727add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            // Unmarshall the results
7737add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            Type* t = NAMES.Search(arg->type.type.data);
7747add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            Variable* v = stubArgs.Get(t);
7757add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            dispatchMethod->statements->Add(new VariableDeclaration(v));
7767add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7777add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            generate_create_from_data(t, dispatchMethod->statements, arg->name.data, v,
7787add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                    resultData, &classLoader);
7797add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7807add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            // Add the argument to the callback
7817add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato            realCall->arguments.push_back(v);
7827add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        }
7837add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        arg = arg->next;
7847add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
7857add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7867add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // Call the callback method
7879d98a089756b692eefeae7f92cca15e121196e0cManuel Roman    IfStatement* ifst = new IfStatement;
7889d98a089756b692eefeae7f92cca15e121196e0cManuel Roman        ifst->expression = new Comparison(new FieldVariable(THIS_VALUE, "callback"), "!=", NULL_VALUE);
7899d98a089756b692eefeae7f92cca15e121196e0cManuel Roman    dispatchMethod->statements->Add(ifst);
7909d98a089756b692eefeae7f92cca15e121196e0cManuel Roman    ifst->statements->Add(realCall);
7917add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
7927add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
7937add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratostatic void
794e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratogenerate_regular_method(const method_type* method, RpcProxyClass* proxyClass,
7950d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato        EndpointBaseClass* serviceBaseClass, ResultDispatcherClass* resultsDispatcherClass,
796e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        int index)
7977add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
7987add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    arg_type* arg;
7997add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
800e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // == the callback interface for results ================================
801e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // the service base class
802e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Type* resultsInterfaceType = generate_results_method(method, proxyClass);
803e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
804e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // == the method in the proxy class =====================================
805e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    generate_proxy_method(method, proxyClass, resultsDispatcherClass, resultsInterfaceType, index);
806e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
807e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // == the method in the result dispatcher class =========================
808e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    if (resultsInterfaceType != NULL) {
809e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        generate_result_dispatcher_method(method, resultsDispatcherClass, resultsInterfaceType,
810e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                index);
811e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    }
812e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
813e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // == The abstract method that the service developers implement ==========
8147add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    Method* decl = new Method;
8157add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        decl->comment = gather_comments(method->comments_token->extra);
8167add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        decl->modifiers = PUBLIC | ABSTRACT;
8177add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        decl->returnType = NAMES.Search(method->type.type.data);
8187add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        decl->returnTypeDimension = method->type.dimension;
8197add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        decl->name = method->name.data;
8207add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    arg = method->args;
8217add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    while (arg != NULL) {
8227add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        decl->parameters.push_back(new Variable(
8237add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                            NAMES.Search(arg->type.type.data), arg->name.data,
8247add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato                            arg->type.dimension));
8257add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        arg = arg->next;
8267add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
8272c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman
8282c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman    // Add the default RpcContext param to all methods
8292c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman    decl->parameters.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
8302c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman
8317add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    serviceBaseClass->elements.push_back(decl);
8327add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
8337add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
834e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // == the dispatch method in the service base class ======================
835e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    serviceBaseClass->AddMethod(method);
836e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato}
8377add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
838e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratostatic void
839e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratogenerate_event_method(const method_type* method, RpcProxyClass* proxyClass,
8400d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato        EndpointBaseClass* serviceBaseClass, ListenerClass* listenerClass,
841c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato        EventListenerClass* presenterClass, int index)
842e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato{
843e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    arg_type* arg;
844e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    listenerClass->needed = true;
8457add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
846e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // == the push method in the service base class =========================
847e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Method* push = new Method;
848e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        push->modifiers = PUBLIC;
849e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        push->name = push_method_name(method->name.data);
850e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        push->statements = new StatementBlock;
851e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        push->returnType = VOID_TYPE;
852e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    serviceBaseClass->elements.push_back(push);
853a1426e61f4004ed8744f81366d15c209fa7cf9b7Joe Onorato
854e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // The local variables
855e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Variable* _data = new Variable(RPC_DATA_TYPE, "_data");
856e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    push->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE)));
8577add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
858e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // Add the arguments
8597add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    arg = method->args;
8607add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    while (arg != NULL) {
861e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        // Function signature
8627add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        Type* t = NAMES.Search(arg->type.type.data);
863e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
864e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        push->parameters.push_back(v);
865a1426e61f4004ed8744f81366d15c209fa7cf9b7Joe Onorato
866e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        // Input parameter marshalling
867e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        generate_write_to_data(t, push->statements,
868e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                new StringLiteralExpression(arg->name.data), v, _data);
869a1426e61f4004ed8744f81366d15c209fa7cf9b7Joe Onorato
870e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        arg = arg->next;
871e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    }
8727add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
873e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // Send the notifications
874e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    push->statements->Add(new MethodCall("pushEvent", 2,
875e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                new StringLiteralExpression(method->name.data),
876e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                new MethodCall(_data, "serialize")));
877e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
878e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // == the event callback dispatcher method  ====================================
879e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    presenterClass->AddMethod(method);
880e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
881e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // == the event method in the listener base class =====================
882e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Method* event = new Method;
883e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        event->modifiers = PUBLIC;
884e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        event->name = method->name.data;
885e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        event->statements = new StatementBlock;
886e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        event->returnType = VOID_TYPE;
887e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    listenerClass->elements.push_back(event);
888e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    arg = method->args;
889e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    while (arg != NULL) {
890e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        event->parameters.push_back(new Variable(
891e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                            NAMES.Search(arg->type.type.data), arg->name.data,
892e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                            arg->type.dimension));
8937add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        arg = arg->next;
8947add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
8952c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman
8962c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman    // Add a final parameter: RpcContext. Contains data about
8972c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman    // incoming request (e.g., certificate)
8982c5eb269bb047d3fdfc05e852f158563a3de6df8Manuel Roman    event->parameters.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0));
8997add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
9007add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
9017add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratostatic void
902e415ecb47952879665b08aacf40988f518f8bda3Joe Onoratogenerate_listener_methods(RpcProxyClass* proxyClass, Type* presenterType, Type* listenerType)
9037add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
904e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // AndroidAtHomePresenter _presenter;
905c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    // void startListening(Listener listener) {
906c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    //     stopListening();
907c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    //     _presenter = new Presenter(_broker, listener);
908c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    //     _presenter.startListening(_endpoint);
909e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // }
910c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    // void stopListening() {
911e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    //     if (_presenter != null) {
912c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    //         _presenter.stopListening();
913e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    //     }
914e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // }
915e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
916e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Variable* _presenter = new Variable(presenterType, "_presenter");
917e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    proxyClass->elements.push_back(new Field(PRIVATE, _presenter));
918e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
919e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    Variable* listener = new Variable(listenerType, "listener");
920e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
921c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    Method* startListeningMethod = new Method;
922c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato        startListeningMethod->modifiers = PUBLIC;
923c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato        startListeningMethod->returnType = VOID_TYPE;
924c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato        startListeningMethod->name = "startListening";
925c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato        startListeningMethod->statements = new StatementBlock;
926c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato        startListeningMethod->parameters.push_back(listener);
927c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    proxyClass->elements.push_back(startListeningMethod);
928c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato
929c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    startListeningMethod->statements->Add(new MethodCall(THIS_VALUE, "stopListening"));
930c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    startListeningMethod->statements->Add(new Assignment(_presenter,
931c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato                new NewExpression(presenterType, 2, proxyClass->broker, listener)));
932c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    startListeningMethod->statements->Add(new MethodCall(_presenter,
933c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato                "startListening", 1, proxyClass->endpoint));
934c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato
935c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    Method* stopListeningMethod = new Method;
936c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato        stopListeningMethod->modifiers = PUBLIC;
937c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato        stopListeningMethod->returnType = VOID_TYPE;
938c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato        stopListeningMethod->name = "stopListening";
939c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato        stopListeningMethod->statements = new StatementBlock;
940c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    proxyClass->elements.push_back(stopListeningMethod);
941e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
942e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    IfStatement* ifst = new IfStatement;
943e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        ifst->expression = new Comparison(_presenter, "!=", NULL_VALUE);
944c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    stopListeningMethod->statements->Add(ifst);
945e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
946c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    ifst->statements->Add(new MethodCall(_presenter, "stopListening"));
947e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    ifst->statements->Add(new Assignment(_presenter, NULL_VALUE));
9487add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
9497add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
9507add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe OnoratoClass*
9517add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onoratogenerate_rpc_interface_class(const interface_type* iface)
9527add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato{
9537add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // the proxy class
9547add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    InterfaceType* interfaceType = static_cast<InterfaceType*>(
9557add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        NAMES.Find(iface->package, iface->name.data));
9567add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    RpcProxyClass* proxy = new RpcProxyClass(iface, interfaceType);
9577add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
958e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // the listener class
959e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    ListenerClass* listener = new ListenerClass(iface);
960e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
961e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    // the presenter class
962c7ec1dc21ae33a976817cc2deefdcb9065c1803bJoe Onorato    EventListenerClass* presenter = new EventListenerClass(iface, listener->type);
963e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato
9647add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // the service base class
9650d2a6b6cf5a541c534f3f0e4c1e1fc2899c86b5fJoe Onorato    EndpointBaseClass* base = new EndpointBaseClass(iface);
9667add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    proxy->elements.push_back(base);
9677add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
9687add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // the result dispatcher
9697add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    ResultDispatcherClass* results = new ResultDispatcherClass();
9707add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
9717add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // all the declared methods of the proxy
9727add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    int index = 0;
9737add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    interface_item_type* item = iface->interface_items;
9747add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    while (item != NULL) {
9757add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        if (item->item_type == METHOD_TYPE) {
976e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            if (NAMES.Search(((method_type*)item)->type.type.data) == EVENT_FAKE_TYPE) {
977e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                generate_event_method((method_type*)item, proxy, base, listener, presenter, index);
978e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            } else {
979e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato                generate_regular_method((method_type*)item, proxy, base, results, index);
980e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato            }
9817add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        }
9827add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        item = item->next;
9837add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        index++;
9847add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
985e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    presenter->DoneWithMethods();
9867add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    base->DoneWithMethods();
9877add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
9887add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    // only add this if there are methods with results / out parameters
9897add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    if (results->needed) {
9907add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato        proxy->elements.push_back(results);
9917add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    }
992e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    if (listener->needed) {
993e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        proxy->elements.push_back(listener);
994e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        proxy->elements.push_back(presenter);
995e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato        generate_listener_methods(proxy, presenter->type, listener->type);
996e415ecb47952879665b08aacf40988f518f8bda3Joe Onorato    }
9977add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato
9987add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato    return proxy;
9997add83bbb52d8783be9c3c68dc3dd4d7f2fead54Joe Onorato}
1000