Current section
Files
Jump to
Current section
Files
src/atproto_codegen.erl
-module(atproto_codegen).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/atproto_codegen.gleam").
-export([main/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Lexicon -> Gleam codegen. Reads `<lexicons_dir>/**/*.json` and writes typed\n"
" modules into `<out_dir>`, importable as `<out_module>/...`. See\n"
" `codegen/lexicon` (parsing), `codegen/naming` (names/refs), `codegen/emit`\n"
" (source emission).\n"
).
-file("src/atproto_codegen.gleam", 161).
-spec parent_dir(binary()) -> binary().
parent_dir(Path) ->
case begin
_pipe = gleam@string:split(Path, <<"/"/utf8>>),
lists:reverse(_pipe)
end of
[_ | Rest] ->
_pipe@1 = Rest,
_pipe@2 = lists:reverse(_pipe@1),
gleam@string:join(_pipe@2, <<"/"/utf8>>);
[] ->
<<"."/utf8>>
end.
-file("src/atproto_codegen.gleam", 91).
-spec internal_template() -> binary().
internal_template() ->
Priv = begin
_pipe = gleam_erlang_ffi:priv_directory(<<"atproto_codegen"/utf8>>),
gleam@result:unwrap(_pipe, <<"priv"/utf8>>)
end,
<<Priv/binary, "/internal.gleam"/utf8>>.
-file("src/atproto_codegen.gleam", 156).
-spec ref_key(binary(), binary()) -> list(binary()).
ref_key(Current, Ref) ->
R = atproto_codegen@naming:parse_ref(Current, Ref),
[<<<<(erlang:element(2, R))/binary, "#"/utf8>>/binary,
(erlang:element(3, R))/binary>>].
-file("src/atproto_codegen.gleam", 147).
-spec field_ref_keys(binary(), atproto_codegen@lexicon:field_type()) -> list(binary()).
field_ref_keys(Current, Ft) ->
case Ft of
{t_ref, Ref} ->
ref_key(Current, Ref);
{t_union, Refs} ->
gleam@list:flat_map(
Refs,
fun(_capture) -> ref_key(Current, _capture) end
);
{t_array, Inner} ->
field_ref_keys(Current, Inner);
_ ->
[]
end.
-file("src/atproto_codegen.gleam", 139).
-spec def_properties(atproto_codegen@lexicon:def()) -> list(atproto_codegen@lexicon:property()).
def_properties(Def) ->
case Def of
{record, _, Props} ->
Props;
{object, _, _, Props@1} ->
Props@1;
_ ->
[]
end.
-file("src/atproto_codegen.gleam", 110).
?DOC(
" Warn about any `ref` that points at a def we never generate (a different\n"
" lexicon's def, an external NSID, or an unsupported def). Such a ref would\n"
" otherwise emit Gleam that doesn't compile, with no signal from codegen.\n"
).
-spec report_unresolved_refs(list(atproto_codegen@lexicon:lexicon())) -> nil.
report_unresolved_refs(Lexicons) ->
Known = gleam@list:flat_map(
Lexicons,
fun(Lex) ->
gleam@list:filter_map(erlang:element(3, Lex), fun(D) -> case D of
{record, Nsid, _} ->
{ok, <<Nsid/binary, "#main"/utf8>>};
{object, Nsid@1, Name, _} ->
{ok,
<<<<Nsid@1/binary, "#"/utf8>>/binary,
Name/binary>>};
_ ->
{error, nil}
end end)
end
),
Refs = gleam@list:flat_map(
Lexicons,
fun(Lex@1) ->
gleam@list:flat_map(
erlang:element(3, Lex@1),
fun(D@1) ->
gleam@list:flat_map(
def_properties(D@1),
fun(P) ->
field_ref_keys(
erlang:element(2, Lex@1),
erlang:element(3, P)
)
end
)
end
)
end
),
_pipe = Refs,
_pipe@1 = gleam@list:unique(_pipe),
_pipe@2 = gleam@list:filter(
_pipe@1,
fun(Key) -> not gleam@list:contains(Known, Key) end
),
gleam@list:each(
_pipe@2,
fun(Key@1) ->
gleam_stdlib:println(
<<<<" WARN unresolved ref "/utf8, Key@1/binary>>/binary,
" (referencing def won't compile)"/utf8>>
)
end
).
-file("src/atproto_codegen.gleam", 98).
-spec load_lexicon(binary()) -> {ok, atproto_codegen@lexicon:lexicon()} |
{error, binary()}.
load_lexicon(Path) ->
gleam@result:'try'(
begin
_pipe = simplifile:read(Path),
gleam@result:map_error(
_pipe,
fun(E) ->
<<"read failed: "/utf8, (gleam@string:inspect(E))/binary>>
end
)
end,
fun(Contents) ->
_pipe@1 = gleam@json:parse(
Contents,
atproto_codegen@lexicon:lexicon_decoder()
),
gleam@result:map_error(
_pipe@1,
fun(E@1) ->
<<"parse failed: "/utf8,
(gleam@string:inspect(E@1))/binary>>
end
)
end
).
-file("src/atproto_codegen.gleam", 40).
-spec run(atproto_codegen@config:config()) -> nil.
run(Cfg) ->
Files@1 = case simplifile:get_files(erlang:element(2, Cfg)) of
{ok, Files} -> Files;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"atproto_codegen"/utf8>>,
function => <<"run"/utf8>>,
line => 41,
value => _assert_fail,
start => 1209,
'end' => 1270,
pattern_start => 1220,
pattern_end => 1229})
end,
Lexicons = begin
_pipe = Files@1,
_pipe@1 = gleam@list:filter(
_pipe,
fun(_capture) ->
gleam_stdlib:string_ends_with(_capture, <<".json"/utf8>>)
end
),
gleam@list:filter_map(_pipe@1, fun(Path) -> case load_lexicon(Path) of
{ok, Lex} ->
{ok, Lex};
{error, Reason} ->
gleam_stdlib:println(
<<<<<<" WARN skipping "/utf8, Path/binary>>/binary,
": "/utf8>>/binary,
Reason/binary>>
),
{error, nil}
end end)
end,
report_unresolved_refs(Lexicons),
case simplifile:create_directory_all(erlang:element(3, Cfg)) of
{ok, _} -> nil;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"atproto_codegen"/utf8>>,
function => <<"run"/utf8>>,
line => 57,
value => _assert_fail@1,
start => 1620,
'end' => 1683,
pattern_start => 1631,
pattern_end => 1636})
end,
Internal@1 = case simplifile:read(internal_template()) of
{ok, Internal} -> Internal;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"atproto_codegen"/utf8>>,
function => <<"run"/utf8>>,
line => 58,
value => _assert_fail@2,
start => 1686,
'end' => 1748,
pattern_start => 1697,
pattern_end => 1709})
end,
case simplifile:write(
<<(erlang:element(3, Cfg))/binary, "/internal.gleam"/utf8>>,
<<"//// Generated by codegen from priv/internal.gleam. Do not edit by hand.\n\n"/utf8,
Internal@1/binary>>
) of
{ok, _} -> nil;
_assert_fail@3 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"atproto_codegen"/utf8>>,
function => <<"run"/utf8>>,
line => 59,
value => _assert_fail@3,
start => 1751,
'end' => 1887,
pattern_start => 1762,
pattern_end => 1767})
end,
gleam@list:each(
Lexicons,
fun(Lex@1) ->
gleam@list:each(erlang:element(3, Lex@1), fun(D) -> case D of
{unsupported, Nsid, Name, Reason@1} ->
gleam_stdlib:println(
<<<<<<<<<<<<" skip "/utf8, Nsid/binary>>/binary,
"#"/utf8>>/binary,
Name/binary>>/binary,
" ("/utf8>>/binary,
Reason@1/binary>>/binary,
")"/utf8>>
);
_ ->
nil
end end),
case atproto_codegen@emit:emit_lexicon(Cfg, Lex@1) of
{some, Source} ->
Path@1 = <<<<<<(erlang:element(3, Cfg))/binary, "/"/utf8>>/binary,
(atproto_codegen@naming:module_subpath(
erlang:element(5, Cfg),
erlang:element(2, Lex@1)
))/binary>>/binary,
".gleam"/utf8>>,
case simplifile:create_directory_all(parent_dir(Path@1)) of
{ok, _} -> nil;
_assert_fail@4 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"atproto_codegen"/utf8>>,
function => <<"run"/utf8>>,
line => 80,
value => _assert_fail@4,
start => 2338,
'end' => 2406,
pattern_start => 2349,
pattern_end => 2354})
end,
case simplifile:write(Path@1, Source) of
{ok, _} -> nil;
_assert_fail@5 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"atproto_codegen"/utf8>>,
function => <<"run"/utf8>>,
line => 81,
value => _assert_fail@5,
start => 2415,
'end' => 2478,
pattern_start => 2426,
pattern_end => 2431})
end,
gleam_stdlib:println(<<" gen "/utf8, Path@1/binary>>);
none ->
nil
end
end
),
gleam_stdlib:println(<<"codegen: done"/utf8>>).
-file("src/atproto_codegen.gleam", 27).
-spec main() -> nil.
main() ->
case erlang:element(4, argv:load()) of
[Lexicons_dir, Out_dir, Out_module, Prefixes] ->
run(
{config,
Lexicons_dir,
Out_dir,
Out_module,
gleam@string:split(Prefixes, <<","/utf8>>)}
);
_ ->
gleam_stdlib:println(
<<"usage: gleam run -- <lexicons_dir> <out_dir> <out_module> <nsid_prefix>[,<nsid_prefix>...]"/utf8>>
)
end.