in compiler/cpp/src/thrift/generate/t_swift_generator.cc [2339:2524]
void t_swift_generator::generate_swift_service_server_implementation(ostream& out,
t_service* tservice) {
string name = tservice->get_name() + "Processor";
indent(out) << "extension " << name << " : TProcessor";
block_open(out);
out << '\n';
indent(out) << "static let processorHandlers" << (gen_cocoa_ ? " " : "") << ": ProcessorHandlerDictionary =";
block_open(out);
out << '\n';
out << indent() << "var processorHandlers = ProcessorHandlerDictionary()" << '\n' << '\n';
// generate method map for routing incoming calls
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) {
t_function* tfunction = *f_iter;
string args_type = function_args_helper_struct_type(tservice, *f_iter);
out << indent() << "processorHandlers[\"" << tfunction->get_name() << "\"] = { sequenceID, inProtocol, outProtocol, handler in" << '\n'
<< '\n';
indent_up();
if (!gen_cocoa_) {
out << indent() << "let args = try " << args_type << ".read(from: inProtocol)" << '\n'
<< '\n'
<< indent() << "try inProtocol.readMessageEnd()" << '\n'
<< '\n';
} else {
out << indent() << "let args = try " << args_type << ".readValueFromProtocol(inProtocol)" << '\n'
<< '\n'
<< indent() << "try inProtocol.readMessageEnd()" << '\n'
<< '\n';
}
if (!tfunction->is_oneway() ) {
string result_type = function_result_helper_struct_type(tservice, tfunction);
indent(out) << "var result = " << result_type << "()" << '\n';
indent(out) << "do";
block_open(out);
indent(out);
if (!tfunction->get_returntype()->is_void()) {
out << "result.success = ";
}
out << "try handler." << (gen_cocoa_ ? function_name(tfunction) : tfunction->get_name()) << "(";
t_struct* arg_struct = tfunction->get_arglist();
const vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator f_iter;
for (f_iter = fields.begin(); f_iter != fields.end();) {
string fieldName = (*f_iter)->get_name();
if (!gen_cocoa_ || f_iter != fields.begin()) {
out << fieldName << ": ";
}
out << "args." << fieldName;
if (++f_iter != fields.end()) {
out << ", ";
}
}
out << ")" << '\n';
block_close(out);
t_struct* xs = tfunction->get_xceptions();
const vector<t_field*>& xfields = xs->get_members();
vector<t_field*>::const_iterator x_iter;
if (!gen_cocoa_) {
for (x_iter = xfields.begin(); x_iter != xfields.end(); ++x_iter) {
indent(out) << "catch let error as ";
t_program* program = (*x_iter)->get_type()->get_program();
if ((*x_iter)->get_type()->get_name() == "Error" && namespaced_ && program != program_) {
out << get_real_swift_module(program) << ".";
}
out << (*x_iter)->get_type()->get_name();
out << " { result." << (*x_iter)->get_name() << " = error }" << '\n';
}
indent(out) << "catch let error { throw error }" << '\n';
out << '\n';
if (!tfunction->is_oneway()) {
out << indent() << "try outProtocol.writeMessageBegin(name: \"" << tfunction->get_name() << "\", type: .reply, sequenceID: sequenceID)" << '\n'
<< indent() << "try result.write(to: outProtocol)" << '\n'
<< indent() << "try outProtocol.writeMessageEnd()" << '\n'
<< indent() << "try outProtocol.transport.flush()" << '\n';
}
} else {
for (x_iter = xfields.begin(); x_iter != xfields.end(); ++x_iter) {
indent(out) << "catch let error as " << (*x_iter)->get_type()->get_name();
block_open(out);
indent(out) << "result." << (*x_iter)->get_name() << " = error" << '\n';
block_close(out);
}
indent(out) << "catch let error";
block_open(out);
out << indent() << "throw error" << '\n';
block_close(out);
out << '\n';
if (!tfunction->is_oneway()) {
out << indent() << "try outProtocol.writeMessageBeginWithName(\"" << tfunction->get_name() << "\", type: .REPLY, sequenceID: sequenceID)" << '\n'
<< indent() << "try " << result_type << ".writeValue(result, toProtocol: outProtocol)" << '\n'
<< indent() << "try outProtocol.writeMessageEnd()" << '\n';
}
}
}
block_close(out);
}
indent(out) << "return processorHandlers" << '\n';
block_close(out,false);
out << "()" << '\n';
out << '\n';
if (!gen_cocoa_) {
indent(out) << "public func process(on inProtocol: TProtocol, outProtocol: TProtocol) throws";
} else {
indent(out) << "public func processOnInputProtocol(inProtocol: TProtocol, outputProtocol outProtocol: TProtocol) throws";
}
block_open(out);
out << '\n';
out << indent() << "let (messageName, _, sequenceID) = try inProtocol.readMessageBegin()" << '\n'
<< '\n'
<< indent() << "if let processorHandler = " << name << ".processorHandlers[messageName]";
block_open(out);
out << indent() << "do";
block_open(out);
out << indent() << "try processorHandler(sequenceID, inProtocol, outProtocol, service)" << '\n';
block_close(out);
if (!gen_cocoa_) {
out << indent() << "catch let error as TApplicationError";
block_open(out);
out << indent() << "try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: error)" << '\n'
<< indent() << "try outProtocol.transport.flush()" << '\n';
block_close(out);
block_close(out);
out << indent() << "else";
block_open(out);
out << indent() << "try inProtocol.skip(type: .struct)" << '\n'
<< indent() << "try inProtocol.readMessageEnd()" << '\n'
<< indent() << "let ex = TApplicationError(error: .unknownMethod(methodName: messageName))" << '\n'
<< indent() << "try outProtocol.writeException(messageName: messageName, sequenceID: sequenceID, ex: ex)" << '\n'
<< indent() << "try outProtocol.transport.flush()" << '\n';
} else {
out << indent() << "catch let error as NSError";
block_open(out);
out << indent() << "try outProtocol.writeExceptionForMessageName(messageName, sequenceID: sequenceID, ex: error)" << '\n';
block_close(out);
block_close(out);
out << indent() << "else";
block_open(out);
out << indent() << "try inProtocol.skipType(.STRUCT)" << '\n'
<< indent() << "try inProtocol.readMessageEnd()" << '\n'
<< indent() << "try outProtocol.writeExceptionForMessageName(messageName," << '\n';
indent_up();
out << indent() << "sequenceID: sequenceID," << '\n'
<< indent() << "ex: NSError(" << '\n';
indent_up();
out << indent() << "domain: TApplicationErrorDomain, " << '\n'
<< indent() << "code: Int(TApplicationError.UnknownMethod.rawValue), " << '\n'
<< indent() << "userInfo: [TApplicationErrorMethodKey: messageName]))" << '\n';
indent_down();
indent_down();
}
block_close(out);
block_close(out);
block_close(out);
out << '\n';
}