void t_delphi_generator::generate_service_server()

in compiler/cpp/src/thrift/generate/t_delphi_generator.cc [2240:2410]


void t_delphi_generator::generate_service_server(t_service* tservice) {
  vector<t_function*> functions = tservice->get_functions();
  vector<t_function*>::iterator f_iter;

  string extends = "";
  string extends_processor = "";

  string full_cls = normalize_clsnm(service_name_, "T") + ".TProcessorImpl";

  if (tservice->get_extends() != nullptr) {
    extends = type_name(tservice->get_extends(), true, true);
    extends_processor = extends + ".TProcessorImpl";
    indent(s_service) << "TProcessorImpl = class(" << extends_processor << ", IProcessor)" << '\n';
  } else {
    indent(s_service) << "TProcessorImpl = class( TInterfacedObject, IProcessor)" << '\n';
  }

  indent(s_service) << "public" << '\n';
  indent_up();
  indent(s_service) << "constructor Create( iface_: Iface );" << '\n';
  indent(s_service) << "destructor Destroy; override;" << '\n';
  indent_down();

  indent_impl(s_service_impl) << "constructor " << full_cls << ".Create( iface_: Iface );" << '\n';
  indent_impl(s_service_impl) << "begin" << '\n';
  indent_up_impl();
  if (tservice->get_extends() != nullptr) {
    indent_impl(s_service_impl) << "inherited Create( iface_);" << '\n';
  } else {
    indent_impl(s_service_impl) << "inherited Create;" << '\n';
  }
  indent_impl(s_service_impl) << "Self.iface_ := iface_;" << '\n';
  if (tservice->get_extends() != nullptr) {
    indent_impl(s_service_impl) << "ASSERT( processMap_ <> nil);  // inherited" << '\n';
  } else {
    indent_impl(s_service_impl)
        << "processMap_ := TThriftDictionaryImpl<string, TProcessFunction>.Create;" << '\n';
  }

  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
    indent_impl(s_service_impl) << "processMap_.AddOrSetValue( '" << (*f_iter)->get_name() << "', "
                                << (*f_iter)->get_name() << "_Process);" << '\n';
  }
  indent_down_impl();
  indent_impl(s_service_impl) << "end;" << '\n' << '\n';

  indent_impl(s_service_impl) << "destructor " << full_cls << ".Destroy;" << '\n';
  indent_impl(s_service_impl) << "begin" << '\n';
  indent_up_impl();
  indent_impl(s_service_impl) << "inherited;" << '\n';
  indent_down_impl();
  indent_impl(s_service_impl) << "end;" << '\n' << '\n';

  indent(s_service) << "private" << '\n';
  indent_up();
  indent(s_service) << "iface_: Iface;" << '\n';
  indent_down();

  if (tservice->get_extends() == nullptr) {
    indent(s_service) << "protected" << '\n';
    indent_up();
    indent(s_service) << "type" << '\n';
    indent_up();
    indent(s_service) << "TProcessFunction = reference to procedure( seqid: System.Integer; const iprot: "
                         "IProtocol; const oprot: IProtocol"
                      << (events_ ? "; const events : IRequestEvents" : "") << ");" << '\n';
    indent_down();
    indent_down();
    indent(s_service) << "protected" << '\n';
    indent_up();
    indent(s_service) << "processMap_: IThriftDictionary<string, TProcessFunction>;" << '\n';
    indent_down();
  }

  indent(s_service) << "public" << '\n';
  indent_up();
  if (extends.empty()) {
    indent(s_service) << "function Process( const iprot: IProtocol; const oprot: IProtocol; const "
                         "events : IProcessorEvents): System.Boolean;" << '\n';
  } else {
    indent(s_service) << "function Process( const iprot: IProtocol; const oprot: IProtocol; const "
                         "events : IProcessorEvents): System.Boolean; reintroduce;" << '\n';
  }

  indent_impl(s_service_impl) << "function " << full_cls << ".Process( const iprot: IProtocol; "
                                                            "const oprot: IProtocol; const events "
                                                            ": IProcessorEvents): System.Boolean;" << '\n';
  ;
  indent_impl(s_service_impl) << "var" << '\n';
  indent_up_impl();
  indent_impl(s_service_impl) << "msg : Thrift.Protocol.TThriftMessage;" << '\n';
  indent_impl(s_service_impl) << "fn : TProcessFunction;" << '\n';
  indent_impl(s_service_impl) << "x : TApplicationException;" << '\n';
  if (events_) {
    indent_impl(s_service_impl) << "context : IRequestEvents;" << '\n';
  }
  indent_down_impl();
  indent_impl(s_service_impl) << "begin" << '\n';
  indent_up_impl();
  indent_impl(s_service_impl) << "try" << '\n';
  indent_up_impl();
  indent_impl(s_service_impl) << "msg := iprot.ReadMessageBegin();" << '\n';
  indent_impl(s_service_impl) << "fn := nil;" << '\n';
  indent_impl(s_service_impl) << "if not processMap_.TryGetValue(msg.Name, fn)" << '\n';
  indent_impl(s_service_impl) << "or not Assigned(fn) then begin" << '\n';
  indent_up_impl();
  indent_impl(s_service_impl) << "TProtocolUtil.Skip(iprot, TType.Struct);" << '\n';
  indent_impl(s_service_impl) << "iprot.ReadMessageEnd();" << '\n';
  indent_impl(s_service_impl) << "x := "
                                 "TApplicationExceptionUnknownMethod.Create("
                                 "'Invalid method name: ''' + msg.Name + '''');" << '\n';
  indent_impl(s_service_impl)
      << "Thrift.Protocol.Init( msg, msg.Name, TMessageType.Exception, msg.SeqID);"
      << '\n';
  indent_impl(s_service_impl) << "oprot.WriteMessageBegin( msg);" << '\n';
  indent_impl(s_service_impl) << "x.Write(oprot);" << '\n';
  indent_impl(s_service_impl) << "oprot.WriteMessageEnd();" << '\n';
  indent_impl(s_service_impl) << "oprot.Transport.Flush();" << '\n';
  indent_impl(s_service_impl) << "Result := True;" << '\n';
  indent_impl(s_service_impl) << "Exit;" << '\n';
  indent_down_impl();
  indent_impl(s_service_impl) << "end;" << '\n';
  if (events_) {
    indent_impl(s_service_impl) << "if events <> nil" << '\n';
    indent_impl(s_service_impl) << "then context := events.CreateRequestContext(msg.Name)" << '\n';
    indent_impl(s_service_impl) << "else context := nil;" << '\n';
    indent_impl(s_service_impl) << "try" << '\n';
    indent_up_impl();
    indent_impl(s_service_impl) << "fn(msg.SeqID, iprot, oprot, context);" << '\n';
    indent_down_impl();
    indent_impl(s_service_impl) << "finally" << '\n';
    indent_up_impl();
    indent_impl(s_service_impl) << "if context <> nil then begin" << '\n';
    indent_up_impl();
    indent_impl(s_service_impl) << "context.CleanupContext;" << '\n';
    indent_impl(s_service_impl) << "context := nil;" << '\n';
    indent_down_impl();
    indent_impl(s_service_impl) << "end;" << '\n';
    indent_down_impl();
    indent_impl(s_service_impl) << "end;" << '\n';
  } else {
    indent_impl(s_service_impl) << "fn(msg.SeqID, iprot, oprot);" << '\n';
  }
  indent_down_impl();
  indent_impl(s_service_impl) << "except" << '\n';
  indent_up_impl();
  indent_impl(s_service_impl) << "on TTransportExceptionTimedOut do begin" << '\n';
  indent_up_impl();
  indent_impl(s_service_impl) << "Result := True;" << '\n';
  indent_impl(s_service_impl) << "Exit;" << '\n';
  indent_down_impl();
  indent_impl(s_service_impl) << "end;" << '\n';
  indent_impl(s_service_impl) << "else begin" << '\n';
  indent_up_impl();
  indent_impl(s_service_impl) << "Result := False;" << '\n';
  indent_impl(s_service_impl) << "Exit;" << '\n';
  indent_down_impl();
  indent_impl(s_service_impl) << "end;" << '\n';
  indent_down_impl();
  indent_impl(s_service_impl) << "end;" << '\n';
  indent_impl(s_service_impl) << "Result := True;" << '\n';
  indent_down_impl();
  indent_impl(s_service_impl) << "end;" << '\n' << '\n';

  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
    generate_process_function(tservice, *f_iter);
  }

  indent_down();
  indent(s_service) << "end;" << '\n' << '\n';
}