void t_java_generator::generate_service_async_client()

in compiler/cpp/src/thrift/generate/t_java_generator.cc [3415:3601]


void t_java_generator::generate_service_async_client(t_service* tservice) {
  string extends_client = "org.apache.thrift.async.TAsyncClient";
  if (tservice->get_extends() != nullptr) {
    extends_client = type_name(tservice->get_extends()) + ".AsyncClient";
  }

  indent(f_service_) << "public static class AsyncClient extends " << extends_client
                     << " implements AsyncIface {" << '\n';
  indent_up();

  // Factory method
  indent(f_service_) << "public static class Factory implements "
                        "org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {"
                     << '\n';
  indent(f_service_) << "  private org.apache.thrift.async.TAsyncClientManager clientManager;"
                     << '\n';
  indent(f_service_) << "  private org.apache.thrift.protocol.TProtocolFactory protocolFactory;"
                     << '\n';
  indent(f_service_) << "  public Factory(org.apache.thrift.async.TAsyncClientManager "
                        "clientManager, org.apache.thrift.protocol.TProtocolFactory "
                        "protocolFactory) {"
                     << '\n';
  indent(f_service_) << "    this.clientManager = clientManager;" << '\n';
  indent(f_service_) << "    this.protocolFactory = protocolFactory;" << '\n';
  indent(f_service_) << "  }" << '\n';
  indent(f_service_) << java_override_annotation() << '\n';
  indent(f_service_) << "  public AsyncClient "
                        "getAsyncClient(org.apache.thrift.transport.TNonblockingTransport "
                        "transport) {"
                     << '\n';
  indent(f_service_) << "    return new AsyncClient(protocolFactory, clientManager, transport);"
                     << '\n';
  indent(f_service_) << "  }" << '\n';
  indent(f_service_) << "}" << '\n' << '\n';

  indent(f_service_) << "public AsyncClient(org.apache.thrift.protocol.TProtocolFactory "
                        "protocolFactory, org.apache.thrift.async.TAsyncClientManager "
                        "clientManager, org.apache.thrift.transport.TNonblockingTransport "
                        "transport) {"
                     << '\n';
  indent(f_service_) << "  super(protocolFactory, clientManager, transport);" << '\n';
  indent(f_service_) << "}" << '\n' << '\n';

  // 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) {
    string funname = (*f_iter)->get_name();
    string sep = "_";
    string javaname = funname;
    if (fullcamel_style_) {
      sep = "";
      javaname = as_camel_case(javaname);
    }
    t_type* ret_type = (*f_iter)->get_returntype();
    t_struct* arg_struct = (*f_iter)->get_arglist();
    string funclassname = funname + "_call";
    const vector<t_field*>& fields = arg_struct->get_members();
    const std::vector<t_field*>& xceptions = (*f_iter)->get_xceptions()->get_members();
    vector<t_field*>::const_iterator fld_iter;
    string args_name = (*f_iter)->get_name() + "_args";
    string result_name = (*f_iter)->get_name() + "_result";

    // Main method body
    indent(f_service_) << java_override_annotation() << '\n';
    indent(f_service_) << "public " << function_signature_async(*f_iter, false)
                       << " throws org.apache.thrift.TException {" << '\n';
    indent(f_service_) << "  checkReady();" << '\n';
    indent(f_service_) << "  " << funclassname << " method_call = new " + funclassname + "("
                       << async_argument_list(*f_iter, arg_struct, ret_type)
                       << ", this, ___protocolFactory, ___transport);" << '\n';
    indent(f_service_) << "  this.___currentMethod = method_call;" << '\n';
    indent(f_service_) << "  ___manager.call(method_call);" << '\n';
    indent(f_service_) << "}" << '\n';

    f_service_ << '\n';

    // TAsyncMethod object for this function call
    indent(f_service_) << "public static class " + funclassname
                              + " extends org.apache.thrift.async.TAsyncMethodCall<"
                              + type_name((*f_iter)->get_returntype(), true) + "> {"
                       << '\n';
    indent_up();

    // Member variables
    for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
      indent(f_service_) << "private " + type_name((*fld_iter)->get_type()) + " "
                                + make_valid_java_identifier((*fld_iter)->get_name()) + ";"
                         << '\n';
    }

    // NOTE since we use a new Client instance to deserialize, let's keep seqid to 0 for now
    // indent(f_service_) << "private int seqid;" << '\n' << '\n';

    // Constructor
    indent(f_service_) << "public " + funclassname + "("
                              + async_argument_list(*f_iter, arg_struct, ret_type, true)
                       << ", org.apache.thrift.async.TAsyncClient client, "
                          "org.apache.thrift.protocol.TProtocolFactory protocolFactory, "
                          "org.apache.thrift.transport.TNonblockingTransport transport) throws "
                          "org.apache.thrift.TException {"
                       << '\n';
    indent(f_service_) << "  super(client, protocolFactory, transport, resultHandler, "
                       << ((*f_iter)->is_oneway() ? "true" : "false") << ");" << '\n';

    // Assign member variables
    for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
      indent(f_service_) << "  this." + make_valid_java_identifier((*fld_iter)->get_name()) + " = " + make_valid_java_identifier((*fld_iter)->get_name())
                                + ";"
                         << '\n';
    }

    indent(f_service_) << "}" << '\n' << '\n';
    indent(f_service_) << java_override_annotation() << '\n';
    indent(f_service_) << "public void write_args(org.apache.thrift.protocol.TProtocol prot) "
                          "throws org.apache.thrift.TException {"
                       << '\n';
    indent_up();

    // Serialize request
    // NOTE we are leaving seqid as 0, for now (see above)
    f_service_ << indent() << "prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage(\""
               << funname << "\", org.apache.thrift.protocol."
               << ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL") << ", 0));"
               << '\n'
               << indent() << args_name << " args = new " << args_name << "();" << '\n';

    for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
      f_service_ << indent() << "args.set" << get_cap_name((*fld_iter)->get_name()) << "("
                 << make_valid_java_identifier((*fld_iter)->get_name()) << ");" << '\n';
    }

    f_service_ << indent() << "args.write(prot);" << '\n'
               << indent() << "prot.writeMessageEnd();" << '\n';

    indent_down();
    indent(f_service_) << "}" << '\n' << '\n';

    // Return method
    indent(f_service_) << java_override_annotation() << '\n';
    indent(f_service_) << "public " + type_name(ret_type, true) + " getResult() throws ";
    vector<t_field*>::const_iterator x_iter;
    for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
      f_service_ << type_name((*x_iter)->get_type(), false, false) + ", ";
    }
    f_service_ << "org.apache.thrift.TException {" << '\n';

    indent_up();
    f_service_
        << indent()
        << "if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {"
        << '\n'
        << indent() << "  throw new java.lang.IllegalStateException(\"Method call not finished!\");"
        << '\n'
        << indent() << "}" << '\n'
        << indent()
        << "org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new "
           "org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());"
        << '\n'
        << indent()
        << "org.apache.thrift.protocol.TProtocol prot = "
           "client.getProtocolFactory().getProtocol(memoryTransport);"
        << '\n';
    indent(f_service_);
    if (ret_type->is_void()) { // NB: Includes oneways which always return void.
      if (!(*f_iter)->is_oneway()) {
        f_service_ << "(new Client(prot)).recv" + sep + javaname + "();" << '\n';
        indent(f_service_);
      }
      f_service_ << "return null;" << '\n';
    } else {
      f_service_ << "return (new Client(prot)).recv" + sep + javaname + "();" << '\n';
    }

    // Close function
    indent_down();
    indent(f_service_) << "}" << '\n';

    // Close class
    indent_down();
    indent(f_service_) << "}" << '\n' << '\n';
  }

  // Close AsyncClient
  scope_down(f_service_);
  f_service_ << '\n';
}