123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183moduleEmbargoId=Capnp_rpc_proto.Message_types.EmbargoIdmoduleRO_array=Capnp_rpc_proto.RO_arraymoduleReader=Capnp_rpc.Private.Schema.ReadermoduleLog=Capnp_rpc.Debug.Log(* A parser for the basic messages (excluding Unimplemented, which has a more complicated type). *)moduleMake_basic(Core_types:Capnp_rpc_proto.S.CORE_TYPES)(Network:S.NETWORK)(T:Capnp_rpc_proto.Message_types.TABLE_TYPES)=structmoduleMessage_types=Capnp_rpc_proto.Message_types.Make(Core_types)(Network.Types)(T)openMessage_typesletparse_xformx=letopenReader.PromisedAnswer.Opinmatchgetxwith|Noop->[]|GetPointerFieldy->[Capnp_rpc.Private.Xform.Fieldy]|Undefined_->failwith"Unknown transform type"letparse_promised_answerpa=letopenReaderinletqid=PromisedAnswer.question_id_getpa|>AnswerId.of_uint32inlettrans=PromisedAnswer.transform_get_listpa|>List.mapparse_xform|>List.concatin`ReceiverAnswer(qid,trans)letparse_descd=letopenReaderinmatchCapDescriptor.getdwith|CapDescriptor.None->`None|CapDescriptor.SenderHostedid->`SenderHosted(ImportId.of_uint32id)|CapDescriptor.SenderPromiseid->`SenderPromise(ImportId.of_uint32id)|CapDescriptor.ReceiverHostedid->`ReceiverHosted(ExportId.of_uint32id)|CapDescriptor.ReceiverAnswerp->parse_promised_answerp|CapDescriptor.ThirdPartyHostedtp->letvine_id=ThirdPartyCapDescriptor.vine_id_gettp|>ImportId.of_uint32inletcap_id=ThirdPartyCapDescriptor.id_gettpin(* todo: for level 3, we should establish a direct connection rather than proxying
through the vine *)`ThirdPartyHosted(Network.parse_third_party_cap_idcap_id,vine_id)|CapDescriptor.Undefined_->failwith"Unknown cap descriptor type"letparse_descs=RO_array.mapparse_descletparse_exnex=letopenReader.Exceptioninletreason=reason_getexinletty=matchtype_getexwith|Failed->`Failed|Overloaded->`Overloaded|Disconnected->`Disconnected|Unimplemented->`Unimplemented|Undefinedx->`Undefinedxin{Capnp_rpc.Exception.ty;reason}letparse_returnreturn=letopenReaderinletqid=Return.answer_id_getreturn|>QuestionId.of_uint32inletrelease_param_caps=Return.release_param_caps_getreturninletret=matchReturn.getreturnwith|Return.Resultsresults->letdescs=parse_descs(Payload.cap_table_get_listresults|>RO_array.of_list)in`Results(Capnp_rpc.Private.Msg.Response.of_readerreturn,descs)|Return.Exceptionex->`Exception(parse_exnex)|Return.Canceled->`Cancelled|Return.ResultsSentElsewhere->`ResultsSentElsewhere|Return.TakeFromOtherQuestionother->`TakeFromOtherQuestion(AnswerId.of_uint32other)|Return.AcceptFromThirdParty_->failwith"TODO: AcceptFromThirdParty"|Return.Undefinedx->failwith(Fmt.str"Unexpected return type received: %d"x)in`Return(qid,ret,release_param_caps)letparse_finishfinish=letopenReaderinletaid=Finish.question_id_getfinish|>AnswerId.of_uint32inletrelease=Finish.release_result_caps_getfinishin`Finish(aid,release)letparse_targetmsg_target=letopenReaderinmatchMessageTarget.getmsg_targetwith|MessageTarget.Undefined_->failwith"Bad MessageTarget"|MessageTarget.ImportedCapid->`ReceiverHosted(ExportId.of_uint32id)|MessageTarget.PromisedAnswerx->parse_promised_answerx(* We have received a question from our peer. *)letparse_callcall=letopenReaderinletaid=Call.question_id_getcall|>AnswerId.of_uint32in(* Resolve capabilities *)letp=Call.params_getcallinletdescs=parse_descs(Payload.cap_table_get_listp|>RO_array.of_list)in(* Get target *)lettarget=parse_target(Call.target_getcall)inletmsg=Capnp_rpc.Private.Msg.Request.of_readercallinletresults_to=letr=Call.send_results_to_getcallinletopenCall.SendResultsToinmatchgetrwith|Caller->`Caller|Yourself->`Yourself|ThirdParty_->failwith"TODO: parse_call: ThirdParty"|Undefinedx->Fmt.failwith"Unknown SendResultsTo type %d"xin`Call(aid,target,msg,descs,results_to)letparse_bootstrapboot=letopenReaderinletqid=Bootstrap.question_id_getboot|>AnswerId.of_uint32inletobject_id=Bootstrap.deprecated_object_id_getboot|>Capnp_rpc.Private.Schema.ReaderOps.string_of_pointerin`Bootstrap(qid,object_id)letparse_disembargox=letopenReaderinlettarget=parse_target(Disembargo.target_getx)inletctx=Disembargo.context_getxinmatchDisembargo.Context.getctxwith|Disembargo.Context.SenderLoopbackembargo_id->`Disembargo_request(`Loopback(target,EmbargoId.of_uint32embargo_id))|Disembargo.Context.ReceiverLoopbackembargo_id->`Disembargo_reply(target,EmbargoId.of_uint32embargo_id)|Disembargo.Context.Accept|Disembargo.Context.Provide_->failwith"TODO: handle_disembargo: 3rd-party"|Disembargo.Context.Undefinedx->Fmt.failwith"Unknown Disembargo type %d"xletparse_resolvex=letopenReaderinletnew_target=matchResolve.getxwith|Resolve.Capd->Ok(parse_descd)|Resolve.Exceptione->Error(parse_exne)|Resolve.Undefinedx->Fmt.failwith"Resolved to Undefined(%d)!"xinletimport_id=Resolve.promise_id_getx|>ImportId.of_uint32in`Resolve(import_id,new_target)letparse_releasex=letopenReaderinletexport_id=Release.id_getx|>ExportId.of_uint32inletref_count=Release.reference_count_getx|>Stdint.Uint32.to_intin`Release(export_id,ref_count)(* Parse a message received from our peer. Returns [`Not_implemented`] if we couldn't understand it. *)letparse_msgmsg=letopenReader.Messageinmatchgetmsgwith|Callx->parse_callx|Bootstrapx->parse_bootstrapx|Returnx->parse_returnx|Finishx->parse_finishx|Disembargox->parse_disembargox|Resolvex->parse_resolvex|Releasex->parse_releasex|Abortx->`Abort(parse_exnx)|Provide_|Accept_|Join_->`Not_implemented(* TODO *)|ObsoleteSave_|ObsoleteDelete_->`Not_implemented|Undefinedx->Log.warn(funf->f"Received Undefined message (%d)!"x);`Not_implemented|Unimplementedx->`UnimplementedxendmoduleMake(EP:Capnp_rpc.Private.Capnp_core.ENDPOINT)(Network:S.NETWORKwithmoduleTypes=EP.Network_types)=structmoduleParse_in=Make_basic(EP.Core_types)(Network)(EP.Table)moduleParse_out=Make_basic(EP.Core_types)(Network)(Capnp_rpc_proto.Message_types.Flip(EP.Table))letmessagemsg=matchParse_in.parse_msgmsgwith|#EP.In.tasmsg->msg|`Not_implemented->`Not_implemented(* We don't understand [msg] *)|`Unimplementedx->(* The remote peer didn't understand [x] *)matchParse_out.parse_msgxwith|#EP.Out.tasmsg->`Unimplementedmsg|`Not_implemented->failwith"Can't read copy of our own message in Unimplemented reply!"|`Unimplemented_->failwith"Peer doesn't implement support for unimplemented message!"end