123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172(************************************************************************)(* Rocq Language Server Protocol *)(* Copyright 2019 MINES ParisTech -- Dual License LGPL 2.1 / GPL3+ *)(* Copyright 2019-2024 Inria -- Dual License LGPL 2.1 / GPL3+ *)(* Copyright 2024-2025 EJGA -- Dual License LGPL 2.1 / GPL3+ *)(* Written by: Emilio J. Gallego Arias *)(************************************************************************)moduleF=FormatmoduleJ=Yojson.Safe(** {1 JSON-RPC input/output} *)(* This needs a fix as to log protocol stuff not using the protocol *)letlog_protocol=ref(fun__->())letset_log_fnfn=log_protocol:=fnletread_raw_messageic=letcl=input_lineicinletsin=Scanf.Scanning.from_stringclinletraw_obj=Scanf.bscanfsin"Content-Length: %d\r"(funsize->letbuf=Bytes.createsizein(* Consume the second \r\n or header *)letohdr=input_lineicin(* If the second line is a return, then no more headers *)let()=ifohdr.[0]='\r'then()else(* Fixme (or use ocaml-lsp) Skip the Content-type header *)ignore(input_lineic)inreally_inputicbuf0size;Bytes.to_stringbuf)inJ.from_stringraw_objletread_raw_messageic=trySome(Ok(read_raw_messageic))with(* if the end of input is encountered while some more characters are needed to
read the current conversion specification, or the lsp server closes *)|End_of_file->None(* if the input does not match the format. *)|Scanf.Scan_failuremsg(* if a conversion to a number is not possible. *)|Failuremsg(* if the format string is invalid. *)|Invalid_argumentmsg->Some(Errormsg)letread_messageic=matchread_raw_messageicwith|None->None(* EOF *)|Some(Okcom)->!log_protocol"read"com;Some(Base.Message.of_yojsoncom)|Some(Errorerr)->Some(Errorerr)letmut=Mutex.create()letsend_jsonfmtobj=Mutex.lockmut;!log_protocol"send"obj;letmsg=if!Fleche.Config.v.pp_jsonthenF.asprintf"%a"J.(pretty_print~std:true)objelseJ.to_stringobj^"\n"inletsize=String.lengthmsginF.fprintffmt"Content-Length: %d\r\n\r\n%s%!"sizemsg;Mutex.unlockmutletsend_messagefmtmessage=send_jsonfmt(Base.Message.to_yojsonmessage)