-module(atproto_codegen@emit@zero). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/atproto_codegen/emit/zero.gleam"). -export([error_to_string/1, compute/1, needs_zero/2, choose_fallback/3]). -export_type([zero_plan/0, zero_error/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(false). -opaque zero_plan() :: {zero_plan, gleam@dict:dict({binary(), binary()}, atproto_codegen@lower:emittable_def()), gleam@dict:dict({binary(), binary()}, boolean()), gleam@dict:dict({binary(), list(binary())}, binary())}. -type zero_error() :: {unzeroable_closed_union, binary(), list(binary())}. -file("src/atproto_codegen/emit/zero.gleam", 32). ?DOC(false). -spec error_to_string(zero_error()) -> binary(). error_to_string(Err) -> case Err of {unzeroable_closed_union, Nsid, Refs} -> <<<<<<<<"closed union in "/utf8, Nsid/binary>>/binary, " has no member with a constructible zero value (refs: "/utf8>>/binary, (gleam@string:join(Refs, <<", "/utf8>>))/binary>>/binary, ")"/utf8>> end. -file("src/atproto_codegen/emit/zero.gleam", 90). ?DOC(false). -spec key_of(binary(), binary()) -> {binary(), binary()}. key_of(Current, Ref) -> R = atproto_codegen@naming:parse_ref(Current, Ref), {erlang:element(2, R), erlang:element(3, R)}. -file("src/atproto_codegen/emit/zero.gleam", 214). ?DOC(false). -spec def_nsid(atproto_codegen@lower:emittable_def()) -> binary(). def_nsid(Def) -> case Def of {emittable_record, Nsid, _} -> Nsid; {emittable_object, Nsid@1, _, _} -> Nsid@1 end. -file("src/atproto_codegen/emit/zero.gleam", 194). ?DOC(false). -spec field_resolvable( gleam@dict:dict({binary(), binary()}, atproto_codegen@lower:emittable_def()), binary(), atproto_codegen@lower:flat_type(), gleam@set:set({binary(), binary()}), gleam@dict:dict({binary(), binary()}, boolean()) ) -> {boolean(), gleam@dict:dict({binary(), binary()}, boolean())}. field_resolvable(Defs, Current, Ft, Visiting, Memo) -> case Ft of {t_ref, Ref} -> resolve_key(Defs, key_of(Current, Ref), Visiting, Memo); {t_union, Refs, closed} -> case resolve_fallback(Defs, Current, Refs, Visiting, Memo) of {{some, _}, Memo2} -> {true, Memo2}; {none, Memo2@1} -> {false, Memo2@1} end; {t_unsupported, _} -> {false, Memo}; _ -> {true, Memo} end. -file("src/atproto_codegen/emit/zero.gleam", 159). ?DOC(false). -spec resolve_def( gleam@dict:dict({binary(), binary()}, atproto_codegen@lower:emittable_def()), {binary(), binary()}, gleam@set:set({binary(), binary()}), gleam@dict:dict({binary(), binary()}, boolean()) ) -> {boolean(), gleam@dict:dict({binary(), binary()}, boolean())}. resolve_def(Defs, Key, Visiting, Memo) -> case gleam_stdlib:map_get(Defs, Key) of {error, nil} -> {false, gleam@dict:insert(Memo, Key, false)}; {ok, Def} -> Visiting2 = gleam@set:insert(Visiting, Key), Own_nsid = def_nsid(Def), {Ok, Memo2} = gleam@list:fold( atproto_codegen@lower:emittable_properties(Def), {true, Memo}, fun(Acc, Field) -> {Ok_acc, Memo_acc} = Acc, case {Ok_acc, erlang:element(4, Field)} of {false, _} -> Acc; {_, false} -> Acc; {true, true} -> field_resolvable( Defs, Own_nsid, erlang:element(3, Field), Visiting2, Memo_acc ) end end ), {Ok, gleam@dict:insert(Memo2, Key, Ok)} end. -file("src/atproto_codegen/emit/zero.gleam", 143). ?DOC(false). -spec resolve_key( gleam@dict:dict({binary(), binary()}, atproto_codegen@lower:emittable_def()), {binary(), binary()}, gleam@set:set({binary(), binary()}), gleam@dict:dict({binary(), binary()}, boolean()) ) -> {boolean(), gleam@dict:dict({binary(), binary()}, boolean())}. resolve_key(Defs, Key, Visiting, Memo) -> case gleam_stdlib:map_get(Memo, Key) of {ok, Known} -> {Known, Memo}; {error, nil} -> case gleam@set:contains(Visiting, Key) of true -> {false, Memo}; false -> resolve_def(Defs, Key, Visiting, Memo) end end. -file("src/atproto_codegen/emit/zero.gleam", 124). ?DOC(false). -spec resolve_fallback( gleam@dict:dict({binary(), binary()}, atproto_codegen@lower:emittable_def()), binary(), list(binary()), gleam@set:set({binary(), binary()}), gleam@dict:dict({binary(), binary()}, boolean()) ) -> {gleam@option:option(binary()), gleam@dict:dict({binary(), binary()}, boolean())}. resolve_fallback(Defs, Current, Refs, Visiting, Memo) -> case Refs of [] -> {none, Memo}; [Ref | Rest] -> {Ok, Memo2} = resolve_key( Defs, key_of(Current, Ref), Visiting, Memo ), case Ok of true -> {{some, Ref}, Memo2}; false -> resolve_fallback(Defs, Current, Rest, Visiting, Memo2) end end. -file("src/atproto_codegen/emit/zero.gleam", 110). ?DOC(false). -spec closed_unions(list(atproto_codegen@lower:flat_lexicon())) -> list({binary(), list(binary())}). closed_unions(Lexicons) -> gleam@list:flat_map( Lexicons, fun(Lex) -> _pipe = atproto_codegen@lower:codec_units(erlang:element(4, Lex)), gleam@list:filter_map(_pipe, fun(Unit) -> case Unit of {union_unit, _, _, Refs, closed} -> {ok, {erlang:element(2, Lex), Refs}}; _ -> {error, nil} end end) end ). -file("src/atproto_codegen/emit/zero.gleam", 95). ?DOC(false). -spec key_of_def(atproto_codegen@lower:emittable_def()) -> {binary(), binary()}. key_of_def(Def) -> case Def of {emittable_record, Nsid, _} -> {Nsid, <<"main"/utf8>>}; {emittable_object, Nsid@1, Name, _} -> {Nsid@1, Name} end. -file("src/atproto_codegen/emit/zero.gleam", 102). ?DOC(false). -spec index_defs(list(atproto_codegen@lower:flat_lexicon())) -> gleam@dict:dict({binary(), binary()}, atproto_codegen@lower:emittable_def()). index_defs(Lexicons) -> _pipe = Lexicons, _pipe@1 = gleam@list:flat_map(_pipe, fun(Lex) -> erlang:element(4, Lex) end), _pipe@2 = gleam@list:filter_map( _pipe@1, fun atproto_codegen@lower:to_emittable/1 ), _pipe@3 = gleam@list:map(_pipe@2, fun(Def) -> {key_of_def(Def), Def} end), maps:from_list(_pipe@3). -file("src/atproto_codegen/emit/zero.gleam", 45). ?DOC(false). -spec compute(list(atproto_codegen@lower:flat_lexicon())) -> {ok, zero_plan()} | {error, zero_error()}. compute(Lexicons) -> Defs = index_defs(Lexicons), gleam@result:'try'( gleam@list:try_fold( closed_unions(Lexicons), {maps:new(), maps:new()}, fun(Acc, U) -> {Memo, Fallbacks} = Acc, {Current, Refs} = U, {Chosen, Memo2} = resolve_fallback( Defs, Current, Refs, gleam@set:new(), Memo ), case Chosen of {some, Ref} -> {ok, {Memo2, gleam@dict:insert( Fallbacks, {Current, Refs}, Ref )}}; none -> {error, {unzeroable_closed_union, Current, Refs}} end end ), fun(_use0) -> {Resolvable, Fallbacks@1} = _use0, {ok, {zero_plan, Defs, Resolvable, Fallbacks@1}} end ). -file("src/atproto_codegen/emit/zero.gleam", 67). ?DOC(false). -spec needs_zero(zero_plan(), atproto_codegen@lower:emittable_def()) -> boolean(). needs_zero(Plan, Def) -> gleam_stdlib:map_get(erlang:element(3, Plan), key_of_def(Def)) =:= {ok, true}. -file("src/atproto_codegen/emit/zero.gleam", 75). ?DOC(false). -spec choose_fallback(zero_plan(), binary(), list(binary())) -> binary(). choose_fallback(Plan, Current, Refs) -> case gleam_stdlib:map_get(erlang:element(4, Plan), {Current, Refs}) of {ok, Ref} -> Ref; {error, nil} -> case Refs of [First | _] -> First; [] -> Current end end.