in thrift/compiler/generate/t_java_deprecated_generator.cc [2485:2716]
void t_java_deprecated_generator::generate_service_client(
const t_service* tservice) {
string extends = "";
string extends_client = "";
if (tservice->get_extends() != nullptr) {
extends = type_name(tservice->get_extends());
extends_client = " extends " + extends + ".Client";
} else {
// Client base class
extends_client = " extends EventHandlerBase";
}
indent(f_service_) << "public static class Client" << extends_client
<< " implements Iface, TClientIf {" << endl;
indent_up();
indent(f_service_) << "public Client(TProtocol prot)" << endl;
scope_up(f_service_);
indent(f_service_) << "this(prot, prot);" << endl;
scope_down(f_service_);
f_service_ << endl;
indent(f_service_) << "public Client(TProtocol iprot, TProtocol oprot)"
<< endl;
scope_up(f_service_);
if (extends.empty()) {
f_service_ << indent() << "iprot_ = iprot;" << endl
<< indent() << "oprot_ = oprot;" << endl;
} else {
f_service_ << indent() << "super(iprot, oprot);" << endl;
}
scope_down(f_service_);
f_service_ << endl;
if (extends.empty()) {
f_service_ << indent() << "protected TProtocol iprot_;" << endl
<< indent() << "protected TProtocol oprot_;" << endl
<< endl
<< indent() << "protected int seqid_;" << endl
<< endl;
f_service_ << indent() << "@Override" << endl
<< indent() << "public TProtocol getInputProtocol()" << endl;
scope_up(f_service_);
indent(f_service_) << "return this.iprot_;" << endl;
scope_down(f_service_);
f_service_ << endl;
f_service_ << indent() << "@Override" << endl
<< indent() << "public TProtocol getOutputProtocol()" << endl;
scope_up(f_service_);
indent(f_service_) << "return this.oprot_;" << endl;
scope_down(f_service_);
f_service_ << endl;
}
// Generate client method implementations
vector<t_function*> functions = tservice->get_functions();
vector<t_function*>::const_iterator f_iter;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
if (!can_generate_method(*f_iter)) {
continue;
}
string funname = (*f_iter)->get_name();
string service_func_name =
"\"" + tservice->get_name() + "." + (*f_iter)->get_name() + "\"";
// Open function
indent(f_service_) << "public " << function_signature(*f_iter) << endl;
scope_up(f_service_);
f_service_ << indent() << "ContextStack ctx = getContextStack("
<< service_func_name << ", null);" << endl
<< indent() << "this.setContextStack(ctx);" << endl
<< indent() << "send_" << funname << "(";
// Get the struct of function call params
const t_struct* arg_struct = (*f_iter)->get_paramlist();
// Declare the function arguments
const vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator fld_iter;
bool first = true;
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
if (first) {
first = false;
} else {
f_service_ << ", ";
}
f_service_ << (*fld_iter)->get_name();
}
f_service_ << ");" << endl;
if ((*f_iter)->qualifier() != t_function_qualifier::one_way) {
f_service_ << indent();
if (!(*f_iter)->get_returntype()->is_void()) {
f_service_ << "return ";
}
f_service_ << "recv_" << funname << "();" << endl;
}
scope_down(f_service_);
f_service_ << endl;
t_function send_function(
&t_base_type::t_void(),
string("send_") + (*f_iter)->get_name(),
t_struct::clone_DO_NOT_USE((*f_iter)->get_paramlist()));
string argsname = (*f_iter)->get_name() + "_args";
// Open function
indent(f_service_) << "public " << function_signature(&send_function)
<< endl;
scope_up(f_service_);
// Serialize the request
indent(f_service_) << "ContextStack ctx = "
<< "this.getContextStack();" << endl;
indent(f_service_) << "super.preWrite(ctx, " << service_func_name
<< ", null);" << endl;
f_service_ << indent() << "oprot_.writeMessageBegin(new TMessage(\""
<< funname << "\", TMessageType.CALL, seqid_));" << endl
<< indent() << argsname << " args = new " << argsname << "();"
<< endl;
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
f_service_ << indent() << "args." << (*fld_iter)->get_name() << " = "
<< (*fld_iter)->get_name() << ";" << endl;
}
string bytes = tmp("_bytes");
string flush = (*f_iter)->qualifier() == t_function_qualifier::one_way
? "onewayFlush"
: "flush";
f_service_ << indent() << "args.write(oprot_);" << endl
<< indent() << "oprot_.writeMessageEnd();" << endl
<< indent() << "oprot_.getTransport()." << flush << "();" << endl
<< indent() << "super.postWrite(ctx, " << service_func_name
<< ", args);" << endl
<< indent() << "return;" << endl;
scope_down(f_service_);
f_service_ << endl;
// Generate recv function only if not a oneway function
if ((*f_iter)->qualifier() != t_function_qualifier::one_way) {
string resultname = (*f_iter)->get_name() + "_result";
t_function recv_function(
(*f_iter)->get_returntype(),
string("recv_") + (*f_iter)->get_name(),
std::make_unique<t_paramlist>(program_),
t_struct::clone_DO_NOT_USE((*f_iter)->get_xceptions()));
// Open the recv function
indent(f_service_) << "public " << function_signature(&recv_function)
<< endl;
scope_up(f_service_);
indent(f_service_) << "ContextStack ctx = "
<< "super.getContextStack();" << endl; // newversion
indent(f_service_) << "long bytes;" << endl;
indent(f_service_) << "TMessageType mtype;" << endl
<< indent() << "super.preRead(ctx, "
<< service_func_name << ");" << endl;
// TODO(mcslee): Message validation here, was the seqid etc ok?
f_service_
<< indent() << "TMessage msg = iprot_.readMessageBegin();" << endl
<< indent() << "if (msg.type == TMessageType.EXCEPTION) {" << endl
<< indent()
<< " TApplicationException x = TApplicationException.read(iprot_);"
<< endl
<< indent() << " iprot_.readMessageEnd();" << endl
<< indent() << " throw x;" << endl
<< indent() << "}" << endl;
if (generate_immutable_structs_) {
f_service_ << indent() << resultname << " result = " << resultname
<< ".deserialize(iprot_);" << endl;
} else {
f_service_ << indent() << resultname << " result = new " << resultname
<< "();" << endl
<< indent() << "result.read(iprot_);" << endl;
}
f_service_ << indent() << "iprot_.readMessageEnd();" << endl
<< indent() << "super.postRead(ctx, " << service_func_name
<< ", result);" << endl
<< endl;
// Careful, only return _result if not a void function
if (!(*f_iter)->get_returntype()->is_void()) {
f_service_ << indent() << "if (result."
<< generate_isset_check("success") << ") {" << endl
<< indent() << " return result.success;" << endl
<< indent() << "}" << endl;
}
const t_struct* xs = (*f_iter)->get_xceptions();
const std::vector<t_field*>& xceptions = xs->get_members();
vector<t_field*>::const_iterator x_iter;
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
f_service_ << indent() << "if (result." << (*x_iter)->get_name()
<< " != null) {" << endl
<< indent() << " throw result." << (*x_iter)->get_name()
<< ";" << endl
<< indent() << "}" << endl;
}
// If you get here it's an exception, unless a void function
if ((*f_iter)->get_returntype()->is_void()) {
indent(f_service_) << "return;" << endl;
} else {
f_service_
<< indent()
<< "throw new TApplicationException(TApplicationException.MISSING_RESULT, \""
<< (*f_iter)->get_name() << " failed: unknown result\");" << endl;
}
// Close function
scope_down(f_service_);
f_service_ << endl;
}
}
indent_down();
indent(f_service_) << "}" << endl;
}