-module(gpb_rpc_compile). -define(AUTO_GEN_HEAD, <<"%% -*- coding: utf-8 -*-\n%% Automatically generated, do not edit\n%% Generated by gpb_rpc_compile\n">>). %% API -export([ gen_router/4, file/5, find_proto_file/4 ]). gen_router(AppDir, RouterFile, GpbRpcOpts, GpbOpts) -> SourceDirs = proplists:lookup_all(i, GpbRpcOpts), {ok, RouterDefines} = to_proto_defines(filename:join([AppDir, RouterFile]), SourceDirs, GpbOpts), {RouterFile0, ErlRenderData, HrlRenderData} = gpb_rpc_tpl_data:router_mod_data(AppDir, RouterFile, GpbRpcOpts, GpbOpts, RouterDefines), % router erl file TargetErlDir = proplists:get_value(o_erl, GpbRpcOpts), ErlTarget = filename:join([TargetErlDir, RouterFile0 ++ ".erl"]), RouterErlTplFile0 = proplists:get_value(router_erl_tpl, GpbRpcOpts), RouterErlTplFile = bbmustache:parse_file(filename:join([AppDir, RouterErlTplFile0])), % router hrl file TargetHrlDir = proplists:get_value(o_hrl, GpbRpcOpts), HrlTarget = filename:join([TargetHrlDir, RouterFile0 ++ ".hrl"]), RouterHrlTplFile0 = proplists:get_value(router_hrl_tpl, GpbRpcOpts), RouterHrlTplFile = bbmustache:parse_file(filename:join([AppDir, RouterHrlTplFile0])), compile_tpl(ErlTarget, RouterErlTplFile, ErlRenderData), compile_tpl(HrlTarget, RouterHrlTplFile, HrlRenderData), ok. file(ProtoFile, ErlTpl, HrlTpl, GpbRpcOpts, GpbOpts) -> SourceDirs = proplists:lookup_all(i, GpbRpcOpts), case to_proto_defines(ProtoFile, SourceDirs, GpbOpts) of {ok, Defines} -> ProtoName = filename:rootname(filename:basename(ProtoFile)), ModuleNameSuffix = proplists:get_value(module_name_suffix, GpbRpcOpts), file_do(ProtoName ++ ModuleNameSuffix, ProtoName, ErlTpl, HrlTpl, GpbRpcOpts, GpbOpts, Defines); Err -> Err end. file_do(FileName, ProtoName, ErlTpl, HrlTpl, GpbRpcOpts, GpbOpts, Defines) -> ModuleNameSuffix = proplists:get_value(module_name_suffix, GpbOpts), GpbProto = ProtoName ++ ModuleNameSuffix, GenMode = proplists:get_value(gen_mode, GpbRpcOpts, server), case {gpb_rpc_tpl_data:mod_file_data(FileName, ProtoName, GpbProto, Defines, GenMode), gpb_rpc_tpl_data:hrl_file_data(FileName, ProtoName, GpbProto, Defines)} of {skip, skip} -> rebar_api:debug("skipped gen gpb rpc & hrl : ~p", [FileName]); {skip, HrlRenderData} -> TargetHrlDir = proplists:get_value(o_hrl, GpbRpcOpts), HrlTarget = filename:join([TargetHrlDir, FileName ++ ".hrl"]), compile_tpl(HrlTarget, HrlTpl, HrlRenderData), rebar_api:debug("skipped gen gpb rpc : ~p", [FileName]); {ErlRenderData, skip} -> rebar_api:debug("skipped gen gpb rpc hrl: ~p", [FileName]), TargetErlDir = proplists:get_value(o_erl, GpbRpcOpts), ErlTarget = filename:join([TargetErlDir, FileName ++ ".erl"]), compile_tpl(ErlTarget, ErlTpl, ErlRenderData); {ErlRenderData, HrlRenderData} -> TargetHrlDir = proplists:get_value(o_hrl, GpbRpcOpts), HrlTarget = filename:join([TargetHrlDir, FileName ++ ".hrl"]), compile_tpl(HrlTarget, HrlTpl, HrlRenderData), TargetErlDir = proplists:get_value(o_erl, GpbRpcOpts), ErlTarget = filename:join([TargetErlDir, FileName ++ ".erl"]), compile_tpl(ErlTarget, ErlTpl, ErlRenderData) end, ok. compile_tpl(Target, Tpl, RenderData) -> IoData = bbmustache:compile(Tpl, RenderData, [{key_type, atom}]), ok = file:write_file(Target, [?AUTO_GEN_HEAD, IoData]). -spec to_proto_defines(ProtoFile :: file:filename(), SourceDirs :: [file:filename()], proplists:proplist()) -> {ok, Defines :: tuple()}. to_proto_defines(ProtoFile, SourceDirs, GpbOpts) -> {ok, Binary} = file:read_file(ProtoFile), String = binary_to_list(Binary), gpb_compile:string(mod, String, [to_proto_defs | SourceDirs] ++ GpbOpts). find_proto_file(AppDir, ProtoName, SourceDirs, GpbOpts) -> lists:foldl( fun({i, SourceDir}, Acc) -> ProtoFile = filename:join([AppDir, SourceDir, ProtoName ++ ".proto"]), case filelib:is_file(ProtoFile) of true -> {ok, Defines} = to_proto_defines(ProtoFile, SourceDirs, GpbOpts), [{ProtoName, Defines} | Acc]; false -> Acc end end, [], SourceDirs).