in compiler/cpp/src/thrift/generate/t_kotlin_generator.cc [1652:1827]
void t_kotlin_generator::generate_service_process_function(ostream& out,
t_service* tservice,
t_function* tfunc) {
string args_name = tservice->get_name() + "FunctionArgs." + tfunc->get_name() + "_args";
string rtype = type_name(tfunc->get_returntype(), true);
string resultname = tservice->get_name() + "FunctionResult." + tfunc->get_name() + "_result";
indent(out) << "class " << tfunc->get_name() << "<I : " << tservice->get_name()
<< ">(private val scope: kotlinx.coroutines.CoroutineScope) : "
"org.apache.thrift.AsyncProcessFunction<I, "
<< args_name << ", " << rtype << ", "
<< (tfunc->is_oneway() ? "org.apache.thrift.TBase<*, *>" : resultname)
<< ">(\"" << tfunc->get_name() << "\"), ProcessFunction {"
<< '\n';
indent_up();
{
indent(out) << "override fun isOneway() = " << (tfunc->is_oneway() ? "true" : "false") << '\n';
indent(out) << "override fun getEmptyArgsInstance() = " << args_name << "()" << '\n';
indent(out) << "override fun getEmptyResultInstance() = ";
if (tfunc->is_oneway()) {
out << "null" << '\n';
}
else {
out << resultname << "()" << '\n';
}
indent(out) << '\n';
indent(out) << "override fun start(iface: I, args: " << args_name
<< ", resultHandler: org.apache.thrift.async.AsyncMethodCallback<" << rtype
<< ">) {" << '\n';
indent_up();
indent(out) << "scope.future {" << '\n';
indent_up();
indent(out) << "iface." << tfunc->get_name() << "(";
{
auto arguments = tfunc->get_arglist();
bool first = true;
for (t_field* tfield : arguments->get_members()) {
if (first) {
first = false;
} else {
out << ", ";
}
out << "args." << tfield->get_name() << "!!";
}
}
out << ")" << '\n';
indent_down();
indent(out) << "}.whenComplete { r, t ->" << '\n';
{
indent_up();
indent(out) << "if (t != null) {" << '\n';
indent_up();
indent(out) << "resultHandler.onError(t as java.lang.Exception)" << '\n';
indent_down();
indent(out) << "} else {" << '\n';
indent_up();
indent(out) << "resultHandler.onComplete(r)" << '\n';
}
scope_down(out);
scope_down(out);
scope_down(out);
indent(out) << "override fun getResultHandler(fb: "
"org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer, seqid: "
"Int) ="
<< '\n';
indent_up();
{
indent(out) << "object : org.apache.thrift.async.AsyncMethodCallback<" << rtype << ">{"
<< '\n';
indent_up();
{
indent(out) << "override fun onComplete(response: " << rtype << ") {" << '\n';
indent_up();
if (tfunc->is_oneway()) {
indent(out) << "// one way function, no result handling" << '\n';
} else {
string result_name
= tservice->get_name() + "FunctionResult." + tfunc->get_name() + "_result";
indent(out) << "val result = " << result_name << "()" << '\n';
if (!tfunc->get_returntype()->is_void()) {
indent(out) << "result.success = response" << '\n';
}
indent(out) << "try {" << '\n';
indent_up();
indent(out)
<< "sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY, seqid)"
<< '\n';
indent_down();
indent(out) << "} catch (e: org.apache.thrift.transport.TTransportException) {" << '\n';
indent_up();
indent(out) << "logger.error(\"TTransportException writing to internal frame buffer\", e)"
<< '\n';
indent(out) << "fb.close()" << '\n';
indent_down();
indent(out) << "} catch (e: Exception) {" << '\n';
indent_up();
indent(out) << "logger.error(\"Exception writing to internal frame buffer\", e)" << '\n';
indent(out) << "onError(e)" << '\n';
scope_down(out);
}
scope_down(out);
}
{
indent(out) << "override fun onError(exception: kotlin.Exception) {" << '\n';
indent_up();
if (tfunc->is_oneway()) {
indent(out) << "if (exception is org.apache.thrift.transport.TTransportException) {"
<< '\n';
indent_up();
indent(out) << "logger.error(\"TTransportException inside handler\", exception)" << '\n';
indent(out) << "fb.close()" << '\n';
indent_down();
indent(out) << "} else {" << '\n';
indent_up();
indent(out) << "logger.error(\"Exception inside oneway handler\", exception)" << '\n';
scope_down(out);
} else {
indent(out) << "val (msgType, msg) = when (exception) {" << '\n';
indent_up();
auto xceptions = tfunc->get_xceptions()->get_members();
for (auto xception : xceptions) {
indent(out) << "is " << type_name(xception->get_type()) << " -> {" << '\n';
indent_up();
string result_name
= tservice->get_name() + "FunctionResult." + tfunc->get_name() + "_result";
indent(out) << "val result = " << result_name << "()" << '\n';
indent(out) << "result." << xception->get_name() << " = exception" << '\n';
indent(out) << "org.apache.thrift.protocol.TMessageType.REPLY to result" << '\n';
scope_down(out);
}
indent(out) << "is org.apache.thrift.transport.TTransportException -> {" << '\n';
indent_up();
indent(out) << "logger.error(\"TTransportException inside handler\", exception)" << '\n';
indent(out) << "fb.close()" << '\n';
indent(out) << "return" << '\n';
scope_down(out);
indent(out) << "is org.apache.thrift.TApplicationException -> {" << '\n';
indent_up();
indent(out) << "logger.error(\"TApplicationException inside handler\", exception)"
<< '\n';
indent(out) << "org.apache.thrift.protocol.TMessageType.EXCEPTION to exception" << '\n';
scope_down(out);
indent(out) << "else -> {" << '\n';
indent_up();
indent(out) << "logger.error(\"Exception inside handler\", exception)" << '\n';
indent(out) << "org.apache.thrift.protocol.TMessageType.EXCEPTION to "
"org.apache.thrift.TApplicationException(org.apache.thrift."
"TApplicationException.INTERNAL_ERROR, exception.message)"
<< '\n';
scope_down(out);
scope_down(out);
indent(out) << "try {" << '\n';
indent_up();
indent(out) << "sendResponse(fb, msg, msgType, seqid)" << '\n';
indent_down();
indent(out) << "} catch (ex: java.lang.Exception) {" << '\n';
indent_up();
indent(out) << "logger.error(\"Exception writing to internal frame buffer\", ex)" << '\n';
indent(out) << "fb.close()" << '\n';
scope_down(out);
}
scope_down(out);
}
scope_down(out);
}
indent_down();
}
scope_down(out);
}