diff options
author | Mike Lockwood <lockwood@google.com> | 2013-08-28 09:44:17 -0700 |
---|---|---|
committer | Mike Lockwood <lockwood@google.com> | 2013-08-28 09:44:17 -0700 |
commit | 9f6a119c8aa276432ece4fe2118bd8a3c9b1067e (patch) | |
tree | 1391656f9ad624aa99d4c7d2880d38121801a424 /tools/aidl/generate_java_rpc.cpp | |
parent | 647b6f5ed276bf93d95e5801e5e8af2802ef5fbb (diff) |
Move frameworks/base/tools/ to frameworks/tools/
Change-Id: I3ffafdab27cc4aca256c3a5806b630795b75d5c8
Diffstat (limited to 'tools/aidl/generate_java_rpc.cpp')
-rw-r--r-- | tools/aidl/generate_java_rpc.cpp | 1001 |
1 files changed, 0 insertions, 1001 deletions
diff --git a/tools/aidl/generate_java_rpc.cpp b/tools/aidl/generate_java_rpc.cpp deleted file mode 100644 index 5e4daccf6334..000000000000 --- a/tools/aidl/generate_java_rpc.cpp +++ /dev/null @@ -1,1001 +0,0 @@ -#include "generate_java.h" -#include "Type.h" -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -Type* SERVICE_CONTEXT_TYPE = new Type("android.content", - "Context", Type::BUILT_IN, false, false, false); -Type* PRESENTER_BASE_TYPE = new Type("android.support.place.connector", - "EventListener", Type::BUILT_IN, false, false, false); -Type* PRESENTER_LISTENER_BASE_TYPE = new Type("android.support.place.connector", - "EventListener.Listener", Type::BUILT_IN, false, false, false); -Type* RPC_BROKER_TYPE = new Type("android.support.place.connector", "Broker", - Type::BUILT_IN, false, false, false); -Type* RPC_CONTAINER_TYPE = new Type("com.android.athome.connector", "ConnectorContainer", - Type::BUILT_IN, false, false, false); -Type* PLACE_INFO_TYPE = new Type("android.support.place.connector", "PlaceInfo", - Type::BUILT_IN, false, false, false); -// TODO: Just use Endpoint, so this works for all endpoints. -Type* RPC_CONNECTOR_TYPE = new Type("android.support.place.connector", "Connector", - Type::BUILT_IN, false, false, false); -Type* RPC_ENDPOINT_INFO_TYPE = new UserDataType("android.support.place.rpc", - "EndpointInfo", true, __FILE__, __LINE__); -Type* RPC_RESULT_HANDLER_TYPE = new UserDataType("android.support.place.rpc", "RpcResultHandler", - true, __FILE__, __LINE__); -Type* RPC_ERROR_LISTENER_TYPE = new Type("android.support.place.rpc", "RpcErrorHandler", - Type::BUILT_IN, false, false, false); -Type* RPC_CONTEXT_TYPE = new UserDataType("android.support.place.rpc", "RpcContext", true, - __FILE__, __LINE__); - -static void generate_create_from_data(Type* t, StatementBlock* addTo, const string& key, - Variable* v, Variable* data, Variable** cl); -static void generate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* from); -static void generate_write_to_data(Type* t, StatementBlock* addTo, Expression* k, Variable* v, - Variable* data); - -static string -format_int(int n) -{ - char str[20]; - sprintf(str, "%d", n); - return string(str); -} - -static string -class_name_leaf(const string& str) -{ - string::size_type pos = str.rfind('.'); - if (pos == string::npos) { - return str; - } else { - return string(str, pos+1); - } -} - -static string -results_class_name(const string& n) -{ - string str = n; - str[0] = toupper(str[0]); - str.insert(0, "On"); - return str; -} - -static string -results_method_name(const string& n) -{ - string str = n; - str[0] = toupper(str[0]); - str.insert(0, "on"); - return str; -} - -static string -push_method_name(const string& n) -{ - string str = n; - str[0] = toupper(str[0]); - str.insert(0, "push"); - return str; -} - -// ================================================= -class DispatcherClass : public Class -{ -public: - DispatcherClass(const interface_type* iface, Expression* target); - virtual ~DispatcherClass(); - - void AddMethod(const method_type* method); - void DoneWithMethods(); - - Method* processMethod; - Variable* actionParam; - Variable* requestParam; - Variable* rpcContextParam; - Variable* errorParam; - Variable* requestData; - Variable* resultData; - IfStatement* dispatchIfStatement; - Expression* targetExpression; - -private: - void generate_process(); -}; - -DispatcherClass::DispatcherClass(const interface_type* iface, Expression* target) - :Class(), - dispatchIfStatement(NULL), - targetExpression(target) -{ - generate_process(); -} - -DispatcherClass::~DispatcherClass() -{ -} - -void -DispatcherClass::generate_process() -{ - // byte[] process(String action, byte[] params, RpcContext context, RpcError status) - this->processMethod = new Method; - this->processMethod->modifiers = PUBLIC; - this->processMethod->returnType = BYTE_TYPE; - this->processMethod->returnTypeDimension = 1; - this->processMethod->name = "process"; - this->processMethod->statements = new StatementBlock; - - this->actionParam = new Variable(STRING_TYPE, "action"); - this->processMethod->parameters.push_back(this->actionParam); - - this->requestParam = new Variable(BYTE_TYPE, "requestParam", 1); - this->processMethod->parameters.push_back(this->requestParam); - - this->rpcContextParam = new Variable(RPC_CONTEXT_TYPE, "context", 0); - this->processMethod->parameters.push_back(this->rpcContextParam); - - this->errorParam = new Variable(RPC_ERROR_TYPE, "errorParam", 0); - this->processMethod->parameters.push_back(this->errorParam); - - this->requestData = new Variable(RPC_DATA_TYPE, "request"); - this->processMethod->statements->Add(new VariableDeclaration(requestData, - new NewExpression(RPC_DATA_TYPE, 1, this->requestParam))); - - this->resultData = new Variable(RPC_DATA_TYPE, "resultData"); - this->processMethod->statements->Add(new VariableDeclaration(this->resultData, - NULL_VALUE)); -} - -void -DispatcherClass::AddMethod(const method_type* method) -{ - arg_type* arg; - - // The if/switch statement - IfStatement* ifs = new IfStatement(); - ifs->expression = new MethodCall(new StringLiteralExpression(method->name.data), "equals", - 1, this->actionParam); - StatementBlock* block = ifs->statements = new StatementBlock; - if (this->dispatchIfStatement == NULL) { - this->dispatchIfStatement = ifs; - this->processMethod->statements->Add(dispatchIfStatement); - } else { - this->dispatchIfStatement->elseif = ifs; - this->dispatchIfStatement = ifs; - } - - // The call to decl (from above) - MethodCall* realCall = new MethodCall(this->targetExpression, method->name.data); - - // args - Variable* classLoader = NULL; - VariableFactory stubArgs("_arg"); - arg = method->args; - while (arg != NULL) { - Type* t = NAMES.Search(arg->type.type.data); - Variable* v = stubArgs.Get(t); - v->dimension = arg->type.dimension; - - // Unmarshall the parameter - block->Add(new VariableDeclaration(v)); - if (convert_direction(arg->direction.data) & IN_PARAMETER) { - generate_create_from_data(t, block, arg->name.data, v, - this->requestData, &classLoader); - } else { - if (arg->type.dimension == 0) { - block->Add(new Assignment(v, new NewExpression(v->type))); - } - else if (arg->type.dimension == 1) { - generate_new_array(v->type, block, v, this->requestData); - } - else { - fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, - __LINE__); - } - } - - // Add that parameter to the method call - realCall->arguments.push_back(v); - - arg = arg->next; - } - - // Add a final parameter: RpcContext. Contains data about - // incoming request (e.g., certificate) - realCall->arguments.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0)); - - Type* returnType = NAMES.Search(method->type.type.data); - if (returnType == EVENT_FAKE_TYPE) { - returnType = VOID_TYPE; - } - - // the real call - bool first = true; - Variable* _result = NULL; - if (returnType == VOID_TYPE) { - block->Add(realCall); - } else { - _result = new Variable(returnType, "_result", - method->type.dimension); - block->Add(new VariableDeclaration(_result, realCall)); - - // need the result RpcData - if (first) { - block->Add(new Assignment(this->resultData, - new NewExpression(RPC_DATA_TYPE))); - first = false; - } - - // marshall the return value - generate_write_to_data(returnType, block, - new StringLiteralExpression("_result"), _result, this->resultData); - } - - // out parameters - int i = 0; - arg = method->args; - while (arg != NULL) { - Type* t = NAMES.Search(arg->type.type.data); - Variable* v = stubArgs.Get(i++); - - if (convert_direction(arg->direction.data) & OUT_PARAMETER) { - // need the result RpcData - if (first) { - block->Add(new Assignment(this->resultData, new NewExpression(RPC_DATA_TYPE))); - first = false; - } - - generate_write_to_data(t, block, new StringLiteralExpression(arg->name.data), - v, this->resultData); - } - - arg = arg->next; - } -} - -void -DispatcherClass::DoneWithMethods() -{ - if (this->dispatchIfStatement == NULL) { - return; - } - - this->elements.push_back(this->processMethod); - - IfStatement* fallthrough = new IfStatement(); - fallthrough->statements = new StatementBlock; - fallthrough->statements->Add(new ReturnStatement( - new MethodCall(SUPER_VALUE, "process", 4, - this->actionParam, this->requestParam, - this->rpcContextParam, - this->errorParam))); - this->dispatchIfStatement->elseif = fallthrough; - IfStatement* s = new IfStatement; - s->statements = new StatementBlock; - this->processMethod->statements->Add(s); - s->expression = new Comparison(this->resultData, "!=", NULL_VALUE); - s->statements->Add(new ReturnStatement(new MethodCall(this->resultData, "serialize"))); - s->elseif = new IfStatement; - s = s->elseif; - s->statements->Add(new ReturnStatement(NULL_VALUE)); -} - -// ================================================= -class RpcProxyClass : public Class -{ -public: - RpcProxyClass(const interface_type* iface, InterfaceType* interfaceType); - virtual ~RpcProxyClass(); - - Variable* endpoint; - Variable* broker; - -private: - void generate_ctor(); - void generate_get_endpoint_info(); -}; - -RpcProxyClass::RpcProxyClass(const interface_type* iface, InterfaceType* interfaceType) - :Class() -{ - this->comment = gather_comments(iface->comments_token->extra); - this->modifiers = PUBLIC; - this->what = Class::CLASS; - this->type = interfaceType; - - // broker - this->broker = new Variable(RPC_BROKER_TYPE, "_broker"); - this->elements.push_back(new Field(PRIVATE, this->broker)); - // endpoint - this->endpoint = new Variable(RPC_ENDPOINT_INFO_TYPE, "_endpoint"); - this->elements.push_back(new Field(PRIVATE, this->endpoint)); - - // methods - generate_ctor(); - generate_get_endpoint_info(); -} - -RpcProxyClass::~RpcProxyClass() -{ -} - -void -RpcProxyClass::generate_ctor() -{ - Variable* broker = new Variable(RPC_BROKER_TYPE, "broker"); - Variable* endpoint = new Variable(RPC_ENDPOINT_INFO_TYPE, "endpoint"); - Method* ctor = new Method; - ctor->modifiers = PUBLIC; - ctor->name = class_name_leaf(this->type->Name()); - ctor->statements = new StatementBlock; - ctor->parameters.push_back(broker); - ctor->parameters.push_back(endpoint); - this->elements.push_back(ctor); - - ctor->statements->Add(new Assignment(this->broker, broker)); - ctor->statements->Add(new Assignment(this->endpoint, endpoint)); -} - -void -RpcProxyClass::generate_get_endpoint_info() -{ - Method* get = new Method; - get->modifiers = PUBLIC; - get->returnType = RPC_ENDPOINT_INFO_TYPE; - get->name = "getEndpointInfo"; - get->statements = new StatementBlock; - this->elements.push_back(get); - - get->statements->Add(new ReturnStatement(this->endpoint)); -} - -// ================================================= -class EventListenerClass : public DispatcherClass -{ -public: - EventListenerClass(const interface_type* iface, Type* listenerType); - virtual ~EventListenerClass(); - - Variable* _listener; - -private: - void generate_ctor(); -}; - -Expression* -generate_get_listener_expression(Type* cast) -{ - return new Cast(cast, new MethodCall(THIS_VALUE, "getView")); -} - -EventListenerClass::EventListenerClass(const interface_type* iface, Type* listenerType) - :DispatcherClass(iface, new FieldVariable(THIS_VALUE, "_listener")) -{ - this->modifiers = PRIVATE; - this->what = Class::CLASS; - this->type = new Type(iface->package ? iface->package : "", - append(iface->name.data, ".Presenter"), - Type::GENERATED, false, false, false); - this->extends = PRESENTER_BASE_TYPE; - - this->_listener = new Variable(listenerType, "_listener"); - this->elements.push_back(new Field(PRIVATE, this->_listener)); - - // methods - generate_ctor(); -} - -EventListenerClass::~EventListenerClass() -{ -} - -void -EventListenerClass::generate_ctor() -{ - Variable* broker = new Variable(RPC_BROKER_TYPE, "broker"); - Variable* listener = new Variable(this->_listener->type, "listener"); - Method* ctor = new Method; - ctor->modifiers = PUBLIC; - ctor->name = class_name_leaf(this->type->Name()); - ctor->statements = new StatementBlock; - ctor->parameters.push_back(broker); - ctor->parameters.push_back(listener); - this->elements.push_back(ctor); - - ctor->statements->Add(new MethodCall("super", 2, broker, listener)); - ctor->statements->Add(new Assignment(this->_listener, listener)); -} - -// ================================================= -class ListenerClass : public Class -{ -public: - ListenerClass(const interface_type* iface); - virtual ~ListenerClass(); - - bool needed; - -private: - void generate_ctor(); -}; - -ListenerClass::ListenerClass(const interface_type* iface) - :Class(), - needed(false) -{ - this->comment = "/** Extend this to listen to the events from this class. */"; - this->modifiers = STATIC | PUBLIC ; - this->what = Class::CLASS; - this->type = new Type(iface->package ? iface->package : "", - append(iface->name.data, ".Listener"), - Type::GENERATED, false, false, false); - this->extends = PRESENTER_LISTENER_BASE_TYPE; -} - -ListenerClass::~ListenerClass() -{ -} - -// ================================================= -class EndpointBaseClass : public DispatcherClass -{ -public: - EndpointBaseClass(const interface_type* iface); - virtual ~EndpointBaseClass(); - - bool needed; - -private: - void generate_ctor(); -}; - -EndpointBaseClass::EndpointBaseClass(const interface_type* iface) - :DispatcherClass(iface, THIS_VALUE), - needed(false) -{ - this->comment = "/** Extend this to implement a link service. */"; - this->modifiers = STATIC | PUBLIC | ABSTRACT; - this->what = Class::CLASS; - this->type = new Type(iface->package ? iface->package : "", - append(iface->name.data, ".EndpointBase"), - Type::GENERATED, false, false, false); - this->extends = RPC_CONNECTOR_TYPE; - - // methods - generate_ctor(); -} - -EndpointBaseClass::~EndpointBaseClass() -{ -} - -void -EndpointBaseClass::generate_ctor() -{ - Variable* container = new Variable(RPC_CONTAINER_TYPE, "container"); - Variable* broker = new Variable(RPC_BROKER_TYPE, "broker"); - Variable* place = new Variable(PLACE_INFO_TYPE, "placeInfo"); - Method* ctor = new Method; - ctor->modifiers = PUBLIC; - ctor->name = class_name_leaf(this->type->Name()); - ctor->statements = new StatementBlock; - ctor->parameters.push_back(container); - ctor->parameters.push_back(broker); - ctor->parameters.push_back(place); - this->elements.push_back(ctor); - - ctor->statements->Add(new MethodCall("super", 3, container, broker, place)); -} - -// ================================================= -class ResultDispatcherClass : public Class -{ -public: - ResultDispatcherClass(); - virtual ~ResultDispatcherClass(); - - void AddMethod(int index, const string& name, Method** method, Variable** param); - - bool needed; - Variable* methodId; - Variable* callback; - Method* onResultMethod; - Variable* resultParam; - SwitchStatement* methodSwitch; - -private: - void generate_ctor(); - void generate_onResult(); -}; - -ResultDispatcherClass::ResultDispatcherClass() - :Class(), - needed(false) -{ - this->modifiers = PRIVATE | FINAL; - this->what = Class::CLASS; - this->type = new Type("_ResultDispatcher", Type::GENERATED, false, false, false); - this->interfaces.push_back(RPC_RESULT_HANDLER_TYPE); - - // methodId - this->methodId = new Variable(INT_TYPE, "methodId"); - this->elements.push_back(new Field(PRIVATE, this->methodId)); - this->callback = new Variable(OBJECT_TYPE, "callback"); - this->elements.push_back(new Field(PRIVATE, this->callback)); - - // methods - generate_ctor(); - generate_onResult(); -} - -ResultDispatcherClass::~ResultDispatcherClass() -{ -} - -void -ResultDispatcherClass::generate_ctor() -{ - Variable* methodIdParam = new Variable(INT_TYPE, "methId"); - Variable* callbackParam = new Variable(OBJECT_TYPE, "cbObj"); - Method* ctor = new Method; - ctor->modifiers = PUBLIC; - ctor->name = class_name_leaf(this->type->Name()); - ctor->statements = new StatementBlock; - ctor->parameters.push_back(methodIdParam); - ctor->parameters.push_back(callbackParam); - this->elements.push_back(ctor); - - ctor->statements->Add(new Assignment(this->methodId, methodIdParam)); - ctor->statements->Add(new Assignment(this->callback, callbackParam)); -} - -void -ResultDispatcherClass::generate_onResult() -{ - this->onResultMethod = new Method; - this->onResultMethod->modifiers = PUBLIC; - this->onResultMethod->returnType = VOID_TYPE; - this->onResultMethod->returnTypeDimension = 0; - this->onResultMethod->name = "onResult"; - this->onResultMethod->statements = new StatementBlock; - this->elements.push_back(this->onResultMethod); - - this->resultParam = new Variable(BYTE_TYPE, "result", 1); - this->onResultMethod->parameters.push_back(this->resultParam); - - this->methodSwitch = new SwitchStatement(this->methodId); - this->onResultMethod->statements->Add(this->methodSwitch); -} - -void -ResultDispatcherClass::AddMethod(int index, const string& name, Method** method, Variable** param) -{ - Method* m = new Method; - m->modifiers = PUBLIC; - m->returnType = VOID_TYPE; - m->returnTypeDimension = 0; - m->name = name; - m->statements = new StatementBlock; - *param = new Variable(BYTE_TYPE, "result", 1); - m->parameters.push_back(*param); - this->elements.push_back(m); - *method = m; - - Case* c = new Case(format_int(index)); - c->statements->Add(new MethodCall(new LiteralExpression("this"), name, 1, this->resultParam)); - c->statements->Add(new Break()); - - this->methodSwitch->cases.push_back(c); -} - -// ================================================= -static void -generate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* from) -{ - fprintf(stderr, "aidl: implement generate_new_array %s:%d\n", __FILE__, __LINE__); - exit(1); -} - -static void -generate_create_from_data(Type* t, StatementBlock* addTo, const string& key, Variable* v, - Variable* data, Variable** cl) -{ - Expression* k = new StringLiteralExpression(key); - if (v->dimension == 0) { - t->CreateFromRpcData(addTo, k, v, data, cl); - } - if (v->dimension == 1) { - //t->ReadArrayFromRpcData(addTo, v, data, cl); - fprintf(stderr, "aidl: implement generate_create_from_data for arrays%s:%d\n", - __FILE__, __LINE__); - } -} - -static void -generate_write_to_data(Type* t, StatementBlock* addTo, Expression* k, Variable* v, Variable* data) -{ - if (v->dimension == 0) { - t->WriteToRpcData(addTo, k, v, data, 0); - } - if (v->dimension == 1) { - //t->WriteArrayToParcel(addTo, v, data); - fprintf(stderr, "aidl: implement generate_write_to_data for arrays%s:%d\n", - __FILE__, __LINE__); - } -} - -// ================================================= -static Type* -generate_results_method(const method_type* method, RpcProxyClass* proxyClass) -{ - arg_type* arg; - - string resultsMethodName = results_method_name(method->name.data); - Type* resultsInterfaceType = new Type(results_class_name(method->name.data), - Type::GENERATED, false, false, false); - - if (!method->oneway) { - Class* resultsClass = new Class; - resultsClass->modifiers = STATIC | PUBLIC; - resultsClass->what = Class::INTERFACE; - resultsClass->type = resultsInterfaceType; - - Method* resultMethod = new Method; - resultMethod->comment = gather_comments(method->comments_token->extra); - resultMethod->modifiers = PUBLIC; - resultMethod->returnType = VOID_TYPE; - resultMethod->returnTypeDimension = 0; - resultMethod->name = resultsMethodName; - if (0 != strcmp("void", method->type.type.data)) { - resultMethod->parameters.push_back(new Variable(NAMES.Search(method->type.type.data), - "_result", method->type.dimension)); - } - arg = method->args; - while (arg != NULL) { - if (convert_direction(arg->direction.data) & OUT_PARAMETER) { - resultMethod->parameters.push_back(new Variable( - NAMES.Search(arg->type.type.data), arg->name.data, - arg->type.dimension)); - } - arg = arg->next; - } - resultsClass->elements.push_back(resultMethod); - - if (resultMethod->parameters.size() > 0) { - proxyClass->elements.push_back(resultsClass); - return resultsInterfaceType; - } - } - //delete resultsInterfaceType; - return NULL; -} - -static void -generate_proxy_method(const method_type* method, RpcProxyClass* proxyClass, - ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index) -{ - arg_type* arg; - Method* proxyMethod = new Method; - proxyMethod->comment = gather_comments(method->comments_token->extra); - proxyMethod->modifiers = PUBLIC; - proxyMethod->returnType = VOID_TYPE; - proxyMethod->returnTypeDimension = 0; - proxyMethod->name = method->name.data; - proxyMethod->statements = new StatementBlock; - proxyClass->elements.push_back(proxyMethod); - - // The local variables - Variable* _data = new Variable(RPC_DATA_TYPE, "_data"); - proxyMethod->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE))); - - // Add the arguments - arg = method->args; - while (arg != NULL) { - if (convert_direction(arg->direction.data) & IN_PARAMETER) { - // Function signature - Type* t = NAMES.Search(arg->type.type.data); - Variable* v = new Variable(t, arg->name.data, arg->type.dimension); - proxyMethod->parameters.push_back(v); - - // Input parameter marshalling - generate_write_to_data(t, proxyMethod->statements, - new StringLiteralExpression(arg->name.data), v, _data); - } - arg = arg->next; - } - - // If there is a results interface for this class - Expression* resultParameter; - if (resultsInterfaceType != NULL) { - // Result interface parameter - Variable* resultListener = new Variable(resultsInterfaceType, "_result"); - proxyMethod->parameters.push_back(resultListener); - - // Add the results dispatcher callback - resultsDispatcherClass->needed = true; - resultParameter = new NewExpression(resultsDispatcherClass->type, 2, - new LiteralExpression(format_int(index)), resultListener); - } else { - resultParameter = NULL_VALUE; - } - - // All proxy methods take an error parameter - Variable* errorListener = new Variable(RPC_ERROR_LISTENER_TYPE, "_errors"); - proxyMethod->parameters.push_back(errorListener); - - // Call the broker - proxyMethod->statements->Add(new MethodCall(new FieldVariable(THIS_VALUE, "_broker"), - "sendRpc", 5, - proxyClass->endpoint, - new StringLiteralExpression(method->name.data), - new MethodCall(_data, "serialize"), - resultParameter, - errorListener)); -} - -static void -generate_result_dispatcher_method(const method_type* method, - ResultDispatcherClass* resultsDispatcherClass, Type* resultsInterfaceType, int index) -{ - arg_type* arg; - Method* dispatchMethod; - Variable* dispatchParam; - resultsDispatcherClass->AddMethod(index, method->name.data, &dispatchMethod, &dispatchParam); - - Variable* classLoader = NULL; - Variable* resultData = new Variable(RPC_DATA_TYPE, "resultData"); - dispatchMethod->statements->Add(new VariableDeclaration(resultData, - new NewExpression(RPC_DATA_TYPE, 1, dispatchParam))); - - // The callback method itself - MethodCall* realCall = new MethodCall( - new Cast(resultsInterfaceType, new FieldVariable(THIS_VALUE, "callback")), - results_method_name(method->name.data)); - - // The return value - { - Type* t = NAMES.Search(method->type.type.data); - if (t != VOID_TYPE) { - Variable* rv = new Variable(t, "rv"); - dispatchMethod->statements->Add(new VariableDeclaration(rv)); - generate_create_from_data(t, dispatchMethod->statements, "_result", rv, - resultData, &classLoader); - realCall->arguments.push_back(rv); - } - } - - VariableFactory stubArgs("arg"); - arg = method->args; - while (arg != NULL) { - if (convert_direction(arg->direction.data) & OUT_PARAMETER) { - // Unmarshall the results - Type* t = NAMES.Search(arg->type.type.data); - Variable* v = stubArgs.Get(t); - dispatchMethod->statements->Add(new VariableDeclaration(v)); - - generate_create_from_data(t, dispatchMethod->statements, arg->name.data, v, - resultData, &classLoader); - - // Add the argument to the callback - realCall->arguments.push_back(v); - } - arg = arg->next; - } - - // Call the callback method - IfStatement* ifst = new IfStatement; - ifst->expression = new Comparison(new FieldVariable(THIS_VALUE, "callback"), "!=", NULL_VALUE); - dispatchMethod->statements->Add(ifst); - ifst->statements->Add(realCall); -} - -static void -generate_regular_method(const method_type* method, RpcProxyClass* proxyClass, - EndpointBaseClass* serviceBaseClass, ResultDispatcherClass* resultsDispatcherClass, - int index) -{ - arg_type* arg; - - // == the callback interface for results ================================ - // the service base class - Type* resultsInterfaceType = generate_results_method(method, proxyClass); - - // == the method in the proxy class ===================================== - generate_proxy_method(method, proxyClass, resultsDispatcherClass, resultsInterfaceType, index); - - // == the method in the result dispatcher class ========================= - if (resultsInterfaceType != NULL) { - generate_result_dispatcher_method(method, resultsDispatcherClass, resultsInterfaceType, - index); - } - - // == The abstract method that the service developers implement ========== - Method* decl = new Method; - decl->comment = gather_comments(method->comments_token->extra); - decl->modifiers = PUBLIC | ABSTRACT; - decl->returnType = NAMES.Search(method->type.type.data); - decl->returnTypeDimension = method->type.dimension; - decl->name = method->name.data; - arg = method->args; - while (arg != NULL) { - decl->parameters.push_back(new Variable( - NAMES.Search(arg->type.type.data), arg->name.data, - arg->type.dimension)); - arg = arg->next; - } - - // Add the default RpcContext param to all methods - decl->parameters.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0)); - - serviceBaseClass->elements.push_back(decl); - - - // == the dispatch method in the service base class ====================== - serviceBaseClass->AddMethod(method); -} - -static void -generate_event_method(const method_type* method, RpcProxyClass* proxyClass, - EndpointBaseClass* serviceBaseClass, ListenerClass* listenerClass, - EventListenerClass* presenterClass, int index) -{ - arg_type* arg; - listenerClass->needed = true; - - // == the push method in the service base class ========================= - Method* push = new Method; - push->modifiers = PUBLIC; - push->name = push_method_name(method->name.data); - push->statements = new StatementBlock; - push->returnType = VOID_TYPE; - serviceBaseClass->elements.push_back(push); - - // The local variables - Variable* _data = new Variable(RPC_DATA_TYPE, "_data"); - push->statements->Add(new VariableDeclaration(_data, new NewExpression(RPC_DATA_TYPE))); - - // Add the arguments - arg = method->args; - while (arg != NULL) { - // Function signature - Type* t = NAMES.Search(arg->type.type.data); - Variable* v = new Variable(t, arg->name.data, arg->type.dimension); - push->parameters.push_back(v); - - // Input parameter marshalling - generate_write_to_data(t, push->statements, - new StringLiteralExpression(arg->name.data), v, _data); - - arg = arg->next; - } - - // Send the notifications - push->statements->Add(new MethodCall("pushEvent", 2, - new StringLiteralExpression(method->name.data), - new MethodCall(_data, "serialize"))); - - // == the event callback dispatcher method ==================================== - presenterClass->AddMethod(method); - - // == the event method in the listener base class ===================== - Method* event = new Method; - event->modifiers = PUBLIC; - event->name = method->name.data; - event->statements = new StatementBlock; - event->returnType = VOID_TYPE; - listenerClass->elements.push_back(event); - arg = method->args; - while (arg != NULL) { - event->parameters.push_back(new Variable( - NAMES.Search(arg->type.type.data), arg->name.data, - arg->type.dimension)); - arg = arg->next; - } - - // Add a final parameter: RpcContext. Contains data about - // incoming request (e.g., certificate) - event->parameters.push_back(new Variable(RPC_CONTEXT_TYPE, "context", 0)); -} - -static void -generate_listener_methods(RpcProxyClass* proxyClass, Type* presenterType, Type* listenerType) -{ - // AndroidAtHomePresenter _presenter; - // void startListening(Listener listener) { - // stopListening(); - // _presenter = new Presenter(_broker, listener); - // _presenter.startListening(_endpoint); - // } - // void stopListening() { - // if (_presenter != null) { - // _presenter.stopListening(); - // } - // } - - Variable* _presenter = new Variable(presenterType, "_presenter"); - proxyClass->elements.push_back(new Field(PRIVATE, _presenter)); - - Variable* listener = new Variable(listenerType, "listener"); - - Method* startListeningMethod = new Method; - startListeningMethod->modifiers = PUBLIC; - startListeningMethod->returnType = VOID_TYPE; - startListeningMethod->name = "startListening"; - startListeningMethod->statements = new StatementBlock; - startListeningMethod->parameters.push_back(listener); - proxyClass->elements.push_back(startListeningMethod); - - startListeningMethod->statements->Add(new MethodCall(THIS_VALUE, "stopListening")); - startListeningMethod->statements->Add(new Assignment(_presenter, - new NewExpression(presenterType, 2, proxyClass->broker, listener))); - startListeningMethod->statements->Add(new MethodCall(_presenter, - "startListening", 1, proxyClass->endpoint)); - - Method* stopListeningMethod = new Method; - stopListeningMethod->modifiers = PUBLIC; - stopListeningMethod->returnType = VOID_TYPE; - stopListeningMethod->name = "stopListening"; - stopListeningMethod->statements = new StatementBlock; - proxyClass->elements.push_back(stopListeningMethod); - - IfStatement* ifst = new IfStatement; - ifst->expression = new Comparison(_presenter, "!=", NULL_VALUE); - stopListeningMethod->statements->Add(ifst); - - ifst->statements->Add(new MethodCall(_presenter, "stopListening")); - ifst->statements->Add(new Assignment(_presenter, NULL_VALUE)); -} - -Class* -generate_rpc_interface_class(const interface_type* iface) -{ - // the proxy class - InterfaceType* interfaceType = static_cast<InterfaceType*>( - NAMES.Find(iface->package, iface->name.data)); - RpcProxyClass* proxy = new RpcProxyClass(iface, interfaceType); - - // the listener class - ListenerClass* listener = new ListenerClass(iface); - - // the presenter class - EventListenerClass* presenter = new EventListenerClass(iface, listener->type); - - // the service base class - EndpointBaseClass* base = new EndpointBaseClass(iface); - proxy->elements.push_back(base); - - // the result dispatcher - ResultDispatcherClass* results = new ResultDispatcherClass(); - - // all the declared methods of the proxy - int index = 0; - interface_item_type* item = iface->interface_items; - while (item != NULL) { - if (item->item_type == METHOD_TYPE) { - if (NAMES.Search(((method_type*)item)->type.type.data) == EVENT_FAKE_TYPE) { - generate_event_method((method_type*)item, proxy, base, listener, presenter, index); - } else { - generate_regular_method((method_type*)item, proxy, base, results, index); - } - } - item = item->next; - index++; - } - presenter->DoneWithMethods(); - base->DoneWithMethods(); - - // only add this if there are methods with results / out parameters - if (results->needed) { - proxy->elements.push_back(results); - } - if (listener->needed) { - proxy->elements.push_back(listener); - proxy->elements.push_back(presenter); - generate_listener_methods(proxy, presenter->type, listener->type); - } - - return proxy; -} |