in compiler/cpp/src/thrift/generate/t_js_generator.cc [1486:1686]
void t_js_generator::generate_process_function(t_service* tservice, t_function* tfunction) {
if (gen_es6_) {
indent(f_service_) << "process_" + tfunction->get_name() + " (seqid, input, output) {" << '\n';
} else {
indent(f_service_) << js_namespace(tservice->get_program()) << service_name_
<< "Processor.prototype.process_" + tfunction->get_name()
+ " = function(seqid, input, output) {" << '\n';
}
if (gen_ts_) {
indent_up();
f_service_ts_ << ts_indent() << "process_" << tfunction->get_name() << "(seqid: number, input: thrift.TProtocol, output: thrift.TProtocol): void;" << '\n';
indent_down();
}
indent_up();
string argsname = js_namespace(program_) + service_name_ + "_" + tfunction->get_name() + "_args";
string resultname = js_namespace(program_) + service_name_ + "_" + tfunction->get_name()
+ "_result";
indent(f_service_) << js_const_type_ << "args = new " << argsname << "();" << '\n' << indent()
<< "args[Symbol.for(\"read\")](input);" << '\n' << indent() << "input.readMessageEnd();" << '\n';
// Generate the function call
t_struct* arg_struct = tfunction->get_arglist();
const std::vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator f_iter;
// Shortcut out here for oneway functions
if (tfunction->is_oneway()) {
indent(f_service_) << "this._handler." << tfunction->get_name() << "(";
bool first = true;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (first) {
first = false;
} else {
f_service_ << ", ";
}
f_service_ << "args." << (*f_iter)->get_name();
}
f_service_ << ");" << '\n';
indent_down();
if (gen_es6_) {
indent(f_service_) << "}" << '\n';
} else {
indent(f_service_) << "};" << '\n';
}
return;
}
// Promise style invocation
indent(f_service_) << "if (this._handler." << tfunction->get_name()
<< ".length === " << fields.size() << ") {" << '\n';
indent_up();
if (gen_es6_) {
indent(f_service_) << "new Promise((resolve) => resolve(this._handler." << tfunction->get_name() << ".bind(this._handler)(" << '\n';
} else {
string maybeComma = (fields.size() > 0 ? "," : "");
indent(f_service_) << "Q.fcall(this._handler." << tfunction->get_name() << ".bind(this._handler)"
<< maybeComma << '\n';
}
indent_up();
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
string maybeComma = (f_iter != fields.end() - 1 ? "," : "");
indent(f_service_) << "args." << (*f_iter)->get_name() << maybeComma << '\n';
}
indent_down();
if (gen_es6_) {
indent(f_service_) << "))).then(result => {" << '\n';
} else {
indent(f_service_) << ").then(function(result) {" << '\n';
}
indent_up();
f_service_ << indent() << js_const_type_ << "result_obj = new " << resultname << "({success: result});" << '\n'
<< indent() << "output.writeMessageBegin(\"" << tfunction->get_name()
<< "\", Thrift.MessageType.REPLY, seqid);" << '\n' << indent()
<< "result_obj[Symbol.for(\"write\")](output);" << '\n' << indent() << "output.writeMessageEnd();" << '\n'
<< indent() << "output.flush();" << '\n';
indent_down();
if (gen_es6_) {
indent(f_service_) << "}).catch(err => {" << '\n';
} else {
indent(f_service_) << "}).catch(function (err) {" << '\n';
}
indent_up();
indent(f_service_) << js_let_type_ << "result;" << '\n';
bool has_exception = false;
t_struct* exceptions = tfunction->get_xceptions();
if (exceptions) {
const vector<t_field*>& members = exceptions->get_members();
for (auto member : members) {
t_type* t = get_true_type(member->get_type());
if (t->is_xception()) {
if (!has_exception) {
has_exception = true;
indent(f_service_) << "if (err instanceof " << js_type_namespace(t->get_program())
<< t->get_name();
} else {
f_service_ << " || err instanceof " << js_type_namespace(t->get_program())
<< t->get_name();
}
}
}
}
if (has_exception) {
f_service_ << ") {" << '\n';
indent_up();
f_service_ << indent() << "result = new " << resultname << "(err);" << '\n' << indent()
<< "output.writeMessageBegin(\"" << tfunction->get_name()
<< "\", Thrift.MessageType.REPLY, seqid);" << '\n';
indent_down();
indent(f_service_) << "} else {" << '\n';
indent_up();
}
f_service_ << indent() << "result = new "
"Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN,"
" err.message);" << '\n' << indent() << "output.writeMessageBegin(\""
<< tfunction->get_name() << "\", Thrift.MessageType.EXCEPTION, seqid);" << '\n';
if (has_exception) {
indent_down();
indent(f_service_) << "}" << '\n';
}
f_service_ << indent() << "result[Symbol.for(\"write\")](output);" << '\n' << indent()
<< "output.writeMessageEnd();" << '\n' << indent() << "output.flush();" << '\n';
indent_down();
indent(f_service_) << "});" << '\n';
indent_down();
// End promise style invocation
// Callback style invocation
indent(f_service_) << "} else {" << '\n';
indent_up();
indent(f_service_) << "this._handler." << tfunction->get_name() << "(";
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
f_service_ << "args." << (*f_iter)->get_name() << ", ";
}
if (gen_es6_) {
f_service_ << "(err, result) => {" << '\n';
} else {
f_service_ << "function (err, result) {" << '\n';
}
indent_up();
indent(f_service_) << js_let_type_ << "result_obj;" << '\n';
indent(f_service_) << "if ((err === null || typeof err === 'undefined')";
if (has_exception) {
const vector<t_field*>& members = exceptions->get_members();
for (auto member : members) {
t_type* t = get_true_type(member->get_type());
if (t->is_xception()) {
f_service_ << " || err instanceof " << js_type_namespace(t->get_program()) << t->get_name();
}
}
}
f_service_ << ") {" << '\n';
indent_up();
f_service_ << indent() << "result_obj = new " << resultname
<< "((err !== null || typeof err === 'undefined') ? err : {success: result});" << '\n' << indent()
<< "output.writeMessageBegin(\"" << tfunction->get_name()
<< "\", Thrift.MessageType.REPLY, seqid);" << '\n';
indent_down();
indent(f_service_) << "} else {" << '\n';
indent_up();
f_service_ << indent() << "result_obj = new "
"Thrift.TApplicationException(Thrift.TApplicationExceptionType.UNKNOWN,"
" err.message);" << '\n' << indent() << "output.writeMessageBegin(\""
<< tfunction->get_name() << "\", Thrift.MessageType.EXCEPTION, seqid);" << '\n';
indent_down();
f_service_ << indent() << "}" << '\n' << indent() << "result_obj[Symbol.for(\"write\")](output);" << '\n' << indent()
<< "output.writeMessageEnd();" << '\n' << indent() << "output.flush();" << '\n';
indent_down();
indent(f_service_) << "});" << '\n';
indent_down();
indent(f_service_) << "}" << '\n';
// End callback style invocation
indent_down();
if (gen_es6_) {
indent(f_service_) << "}" << '\n';
} else {
indent(f_service_) << "};" << '\n';
}
}