123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121(*
Copyright 2009, 2010, 2011, 2012, 2013, 2014 Anton Lavrik
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*)(*
* common piqi compiler interfaces used by "piqi compile" and piqic-ocaml
*)moduleC=Piqi_commonopenCletflag_strict=reffalseletarg__strict=let(name,_setter,descr)=Piqi_command.arg__strictin(* override the original setter but keep the option name and the description;
* we do this, because although it means the same, it is applied at a later
* stage -- we control it manually below *)(name,Arg.Setflag_strict,descr)letgetopt_speclist=Piqi_command.common_speclist@[arg__strict;Piqi_command.arg__include_extension;]letload_self_spec?(filename="")buf=trace"piqi_compile: loading self-spec from %s\n"(U.quotefilename);trace_enter();letself_spec=try(* TODO: we can read piqi directly using Piqi_piqi.parse_piqi, because
* self-spec is guaranteed to not have any incompatibilities with
* piqi_lang including functions and other parts. This makes "piqi
* compile" start faster than if we used "Piqi.piqi_of_pb buf" *)Piqi.piqi_of_pbbuf(* NOTE: not caching the loaded module *)withexn->Printf.eprintf"error: failed to load self-spec from %s:\n"(U.quotefilename);raiseexn(* try to give more details about what when wrong *)intrace_leave();self_specletget_self_spec_piqtype?(filename="")self_spectypename=letpiqi_def=tryPiqi_db.find_local_typedefself_spec.P.resolved_typedeftypenamewithNot_found->Printf.eprintf"invalid self-spec read from %s: no definition named %s\n"(U.quotefilename)(U.quotetypename);piqi_error"piqi compile: invalid self-spec"in(piqi_def:T.typedef:>T.piqtype)(* make piqi/piqi-list top-level record from the list of piqi piqobjs *)letmake_piqi_list_piqobjpiqi_list_piqtype(piqi_piqobj_list:Piqobj.objlist):Piqobj.obj=letr=matchpiqi_list_piqtypewith|`recordr->r|_->assertfalsein(* the first and the only record field should correspond to the piqi type *)letf=List.hdr.R.fieldinletfields=List.map(funx->Piqobj.Field.({t=f;obj=Somex}))piqi_piqobj_listinletrecord=Piqobj.Record.({t=r;field=fields;unparsed_piq_fields_ref=None})in`recordrecord(* public library API; currently called only from Piqic_ocaml *)letcompile?(extensions=[])self_spec_binifile=trace"compile_to_pb:\n";trace_enter();(* TODO: restore the state after we are done *)List.iter(fune->Piqi_config.add_include_extensione)extensions;letbuf=Piqi_piqirun.init_from_stringself_spec_bininletself_spec=load_self_specbufinletch=Piqi_command.open_inputifileinletpiqi=Piqi.load_piqiifilechintrace"getting all imported dependencies\n";letpiqi_list=Piqi.get_piqi_depspiqiin(* get necessary piqtypes from the self-spec *)letpiqi_piqtype=get_self_spec_piqtypeself_spec"piqi"inletpiqi_list_piqtype=get_self_spec_piqtypeself_spec"piqi-list"intrace"converting modules to internal representation\n";Config.flag_strict:=!flag_strict;(* convert all modules to internal representation *)letpiqobj_list=List.map(funpiqi->Piqi.piqi_to_piqobjpiqi~piqi_piqtype~add_codes:true)piqi_listintrace"generating pb\n";letpiqobj=make_piqi_list_piqobjpiqi_list_piqtypepiqobj_listinletres=Piqi_convert.to_pb_string(Piqi_convert.Piqobjpiqobj)intrace_leave();res