in thrift/compiler/generate/t_hack_generator.cc [4667:4813]
void t_hack_generator::generate_process_function(
const t_service* tservice, const t_function* tfunction, bool async) {
// Open function
indent(f_service_)
<< "protected" << (async ? " async" : "") << " function process_"
<< tfunction->name()
<< "(int $seqid, \\TProtocol $input, \\TProtocol $output): "
<< (async ? "Awaitable<void>" : "void") << " {\n";
indent_up();
std::string service_name = hack_name(tservice);
std::string argsname = generate_function_helper_name(
tservice, tfunction, PhpFunctionNameSuffix::ARGS);
std::string resultname = generate_function_helper_name(
tservice, tfunction, PhpFunctionNameSuffix::RESULT);
const std::string& fn_name = tfunction->name();
f_service_ << indent()
<< "$handler_ctx = $this->eventHandler_->getHandlerContext('"
<< fn_name << "');\n"
<< indent() << "$reply_type = \\TMessageType::REPLY;\n"
<< "\n"
<< indent() << "$this->eventHandler_->preRead($handler_ctx, '"
<< fn_name << "', dict[]);\n"
<< "\n"
<< indent() << "if ($input is \\TBinaryProtocolAccelerated) {\n"
<< indent() << " $args = \\thrift_protocol_read_binary_struct("
<< "$input, '" << argsname << "');\n"
<< indent()
<< "} else if ($input is \\TCompactProtocolAccelerated) {"
<< "\n"
<< indent()
<< " $args = \\thrift_protocol_read_compact_struct($input, '"
<< argsname << "');\n"
<< indent() << "} else {\n"
<< indent() << " $args = " << argsname
<< "::withDefaultValues();\n"
<< indent() << " $args->read($input);\n"
<< indent() << "}\n";
f_service_ << indent() << "$input->readMessageEnd();\n";
f_service_ << indent() << "$this->eventHandler_->postRead($handler_ctx, '"
<< fn_name << "', $args);\n";
// Declare result for non oneway function
if (tfunction->qualifier() != t_function_qualifier::one_way) {
f_service_ << indent() << "$result = " << resultname
<< "::withDefaultValues();\n";
}
// Try block for a function with exceptions
f_service_ << indent() << "try {\n";
indent_up();
// Generate the function call
indent(f_service_) << "$this->eventHandler_->preExec($handler_ctx, '"
<< service_name << "', '" << fn_name << "', $args);\n";
f_service_ << indent();
if (tfunction->qualifier() != t_function_qualifier::one_way &&
!tfunction->get_returntype()->is_void()) {
f_service_ << "$result->success = ";
}
f_service_ << (async ? "await " : "") << "$this->handler->"
<< tfunction->name() << "(";
auto delim = "";
for (const auto& param : tfunction->get_paramlist()->fields()) {
f_service_ << delim << "$args->" << param.name();
delim = ", ";
}
f_service_ << ");\n";
if (tfunction->qualifier() != t_function_qualifier::one_way) {
indent(f_service_) << "$this->eventHandler_->postExec($handler_ctx, '"
<< fn_name << "', $result);\n";
}
indent_down();
int exc_num = 0;
for (const auto& x : t_throws::or_empty(tfunction->exceptions())->fields()) {
f_service_ << indent() << "} catch (" << hack_name(x.get_type()) << " $exc"
<< exc_num << ") {\n";
if (tfunction->qualifier() != t_function_qualifier::one_way) {
indent_up();
f_service_ << indent()
<< "$this->eventHandler_->handlerException($handler_ctx, '"
<< fn_name << "', $exc" << exc_num << ");\n"
<< indent() << "$result->" << x.name() << " = $exc" << exc_num
<< ";\n";
indent_down();
}
++exc_num;
}
f_service_
<< indent() << "} catch (\\Exception $ex) {\n"
<< indent() << " $reply_type = \\TMessageType::EXCEPTION;\n"
<< indent() << " $this->eventHandler_->handlerError($handler_ctx, '"
<< fn_name << "', $ex);\n"
<< indent()
<< " $result = new \\TApplicationException($ex->getMessage().\"\\n\".$ex->getTraceAsString());\n"
<< indent() << "}\n";
// Shortcut out here for oneway functions
if (tfunction->qualifier() == t_function_qualifier::one_way) {
f_service_ << indent() << "return;\n";
indent_down();
f_service_ << indent() << "}\n";
return;
}
f_service_ << indent() << "$this->eventHandler_->preWrite($handler_ctx, '"
<< fn_name << "', $result);\n";
f_service_ << indent() << "if ($output is \\TBinaryProtocolAccelerated)\n";
scope_up(f_service_);
f_service_ << indent() << "\\thrift_protocol_write_binary($output, '"
<< tfunction->name()
<< "', $reply_type, $result, $seqid, $output->isStrictWrite());\n";
scope_down(f_service_);
f_service_ << indent()
<< "else if ($output is \\TCompactProtocolAccelerated)\n";
scope_up(f_service_);
f_service_ << indent() << "\\thrift_protocol_write_compact($output, '"
<< tfunction->name() << "', $reply_type, $result, $seqid);\n";
scope_down(f_service_);
f_service_ << indent() << "else\n";
scope_up(f_service_);
// Serialize the request header
f_service_ << indent() << "$output->writeMessageBegin(\"" << tfunction->name()
<< "\", $reply_type, $seqid);\n"
<< indent() << "$result->write($output);\n"
<< indent() << "$output->writeMessageEnd();\n"
<< indent() << "$output->getTransport()->flush();\n";
scope_down(f_service_);
f_service_ << indent() << "$this->eventHandler_->postWrite($handler_ctx, '"
<< fn_name << "', $result);\n";
// Close function
indent_down();
f_service_ << indent() << "}\n";
}