-module(atproto_codegen@emit). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/atproto_codegen/emit.gleam"). -export([emit_lexicon/2]). -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( " Emit Gleam source (types + `gleam/json` encoders + `gleam/dynamic/decode`\n" " decoders) from lexicon defs, plus the fixed `internal` helper module.\n" ). -file("src/atproto_codegen/emit.gleam", 21). -spec escape(binary()) -> binary(). escape(Value) -> _pipe = Value, _pipe@1 = gleam@string:replace(_pipe, <<"\\"/utf8>>, <<"\\\\"/utf8>>), gleam@string:replace(_pipe@1, <<"\""/utf8>>, <<"\\\""/utf8>>). -file("src/atproto_codegen/emit.gleam", 27). -spec type_uses_helper(atproto_codegen@lexicon:field_type()) -> boolean(). type_uses_helper(Ft) -> case Ft of t_cid_link -> true; t_bytes -> true; t_unknown -> true; {t_array, Inner} -> type_uses_helper(Inner); _ -> false end. -file("src/atproto_codegen/emit.gleam", 35). -spec type_uses_blob(atproto_codegen@lexicon:field_type()) -> boolean(). type_uses_blob(Ft) -> case Ft of t_blob -> true; {t_array, Inner} -> type_uses_blob(Inner); _ -> false end. -file("src/atproto_codegen/emit.gleam", 43). -spec type_uses_unknown(atproto_codegen@lexicon:field_type()) -> boolean(). type_uses_unknown(Ft) -> case Ft of t_unknown -> true; {t_array, Inner} -> type_uses_unknown(Inner); _ -> false end. -file("src/atproto_codegen/emit.gleam", 51). -spec gleam_type( atproto_codegen@config:config(), binary(), atproto_codegen@lexicon:field_type() ) -> binary(). gleam_type(Cfg, Current, Ft) -> case Ft of t_string -> <<"String"/utf8>>; t_int -> <<"Int"/utf8>>; t_bool -> <<"Bool"/utf8>>; t_number -> <<"Float"/utf8>>; {t_ref, Ref} -> R = atproto_codegen@naming:parse_ref(Current, Ref), <<(atproto_codegen@naming:qualifier( erlang:element(5, Cfg), Current, erlang:element(2, R) ))/binary, (atproto_codegen@naming:ref_type_name(erlang:element(5, Cfg), R))/binary>>; {t_array, Inner} -> <<<<"List("/utf8, (gleam_type(Cfg, Current, Inner))/binary>>/binary, ")"/utf8>>; t_cid_link -> <<"String"/utf8>>; t_bytes -> <<"BitArray"/utf8>>; t_blob -> <<"blob.Blob"/utf8>>; t_unknown -> <<"dynamic.Dynamic"/utf8>>; {t_unsupported, Kind} -> <<"Dynamic_"/utf8, Kind/binary>> end. -file("src/atproto_codegen/emit.gleam", 71). -spec encoder_expr( atproto_codegen@config:config(), binary(), atproto_codegen@lexicon:field_type() ) -> binary(). encoder_expr(Cfg, Current, Ft) -> case Ft of t_string -> <<"json.string"/utf8>>; t_int -> <<"json.int"/utf8>>; t_bool -> <<"json.bool"/utf8>>; t_number -> <<"json.float"/utf8>>; {t_ref, Ref} -> R = atproto_codegen@naming:parse_ref(Current, Ref), <<<<(atproto_codegen@naming:qualifier( erlang:element(5, Cfg), Current, erlang:element(2, R) ))/binary, "encode_"/utf8>>/binary, (justin:snake_case( atproto_codegen@naming:ref_type_name( erlang:element(5, Cfg), R ) ))/binary>>; {t_array, Inner} -> <<<<"fn(items) { json.array(items, "/utf8, (encoder_expr(Cfg, Current, Inner))/binary>>/binary, ") }"/utf8>>; t_cid_link -> <<"internal.encode_cid_link"/utf8>>; t_bytes -> <<"internal.encode_bytes"/utf8>>; t_blob -> <<"blob.encode_blob"/utf8>>; t_unknown -> <<"internal.dynamic_to_json"/utf8>>; {t_unsupported, _} -> <<"json.string"/utf8>> end. -file("src/atproto_codegen/emit.gleam", 95). -spec decoder_expr( atproto_codegen@config:config(), binary(), atproto_codegen@lexicon:field_type() ) -> binary(). decoder_expr(Cfg, Current, Ft) -> case Ft of t_string -> <<"decode.string"/utf8>>; t_int -> <<"decode.int"/utf8>>; t_bool -> <<"decode.bool"/utf8>>; t_number -> <<"decode.float"/utf8>>; {t_ref, Ref} -> R = atproto_codegen@naming:parse_ref(Current, Ref), <<<<(atproto_codegen@naming:qualifier( erlang:element(5, Cfg), Current, erlang:element(2, R) ))/binary, (justin:snake_case( atproto_codegen@naming:ref_type_name( erlang:element(5, Cfg), R ) ))/binary>>/binary, "_decoder()"/utf8>>; {t_array, Inner} -> <<<<"decode.list("/utf8, (decoder_expr(Cfg, Current, Inner))/binary>>/binary, ")"/utf8>>; t_cid_link -> <<"internal.cid_link_decoder()"/utf8>>; t_bytes -> <<"internal.bytes_decoder()"/utf8>>; t_blob -> <<"blob.blob_decoder()"/utf8>>; t_unknown -> <<"decode.dynamic"/utf8>>; {t_unsupported, _} -> <<"decode.string"/utf8>> end. -file("src/atproto_codegen/emit.gleam", 186). -spec ref_nsids(atproto_codegen@lexicon:field_type()) -> list(binary()). ref_nsids(Ft) -> case Ft of {t_ref, Ref} -> R = atproto_codegen@naming:parse_ref(<<""/utf8>>, Ref), case erlang:element(2, R) of <<""/utf8>> -> []; Nsid -> [Nsid] end; {t_array, Inner} -> ref_nsids(Inner); _ -> [] end. -file("src/atproto_codegen/emit.gleam", 178). -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/emit.gleam", 134). -spec emit_header( atproto_codegen@config:config(), binary(), list(atproto_codegen@lexicon:def()) ) -> binary(). emit_header(Cfg, Nsid, Defs) -> Props = gleam@list:flat_map(Defs, fun def_properties/1), Needs_option = gleam@list:any(Props, fun(P) -> not erlang:element(4, P) end), Uses_helper = gleam@list:any( Props, fun(P@1) -> type_uses_helper(erlang:element(3, P@1)) end ), Uses_unknown = gleam@list:any( Props, fun(P@2) -> type_uses_unknown(erlang:element(3, P@2)) end ), Uses_blob = gleam@list:any( Props, fun(P@3) -> type_uses_blob(erlang:element(3, P@3)) end ), Externals = begin _pipe = Props, _pipe@1 = gleam@list:flat_map( _pipe, fun(P@4) -> ref_nsids(erlang:element(3, P@4)) end ), _pipe@2 = gleam@list:filter(_pipe@1, fun(N) -> N /= Nsid end), _pipe@3 = gleam@list:unique(_pipe@2), gleam@list:sort(_pipe@3, fun gleam@string:compare/2) end, Base = [<<"import gleam/dynamic/decode"/utf8>>, <<"import gleam/json"/utf8>>, <<"import gleam/list"/utf8>>], Blob = case Uses_blob of true -> [<<"import atproto/blob"/utf8>>]; false -> [] end, Dyn = case Uses_unknown of true -> [<<"import gleam/dynamic"/utf8>>]; false -> [] end, Opt = case Needs_option of true -> [<<"import gleam/option.{type Option}"/utf8>>]; false -> [] end, Internal = case Needs_option orelse Uses_helper of true -> [<<<<"import "/utf8, (erlang:element(4, Cfg))/binary>>/binary, "/internal"/utf8>>]; false -> [] end, Ext = gleam@list:map( Externals, fun(N@1) -> <<<<<<<<<<"import "/utf8, (erlang:element(4, Cfg))/binary>>/binary, "/"/utf8>>/binary, (atproto_codegen@naming:module_subpath( erlang:element(5, Cfg), N@1 ))/binary>>/binary, " as "/utf8>>/binary, (atproto_codegen@naming:module_alias( erlang:element(5, Cfg), N@1 ))/binary>> end ), <<(gleam@string:join( lists:append([Blob, Base, Dyn, Opt, Internal, Ext]), <<"\n"/utf8>> ))/binary, "\n"/utf8>>. -file("src/atproto_codegen/emit.gleam", 296). -spec emit_decoder( atproto_codegen@config:config(), binary(), binary(), list(atproto_codegen@lexicon:property()) ) -> binary(). emit_decoder(Cfg, Nsid, Name, Props) -> Uses = gleam@list:map( Props, fun(P) -> Var = atproto_codegen@naming:field_name(erlang:element(2, P)), case erlang:element(4, P) of true -> <<<<<<<<<<<<" use "/utf8, Var/binary>>/binary, " <- decode.field(\""/utf8>>/binary, (escape(erlang:element(2, P)))/binary>>/binary, "\", "/utf8>>/binary, (decoder_expr(Cfg, Nsid, erlang:element(3, P)))/binary>>/binary, ")"/utf8>>; false -> <<<<<<<<<<<<" use "/utf8, Var/binary>>/binary, " <- decode.optional_field(\""/utf8>>/binary, (escape(erlang:element(2, P)))/binary>>/binary, "\", option.None, decode.optional("/utf8>>/binary, (decoder_expr(Cfg, Nsid, erlang:element(3, P)))/binary>>/binary, "))"/utf8>> end end ), Constructor = case Props of [] -> <<<<" decode.success("/utf8, Name/binary>>/binary, ")"/utf8>>; _ -> <<<<<<<<" decode.success("/utf8, Name/binary>>/binary, "("/utf8>>/binary, (gleam@string:join( gleam@list:map( Props, fun(P@1) -> <<(atproto_codegen@naming:field_name( erlang:element(2, P@1) ))/binary, ":"/utf8>> end ), <<", "/utf8>> ))/binary>>/binary, "))"/utf8>> end, <<<<<<<<<<<<<<<<"pub fn "/utf8, (justin:snake_case(Name))/binary>>/binary, "_decoder() -> decode.Decoder("/utf8>>/binary, Name/binary>>/binary, ") {\n"/utf8>>/binary, (gleam@string:join(Uses, <<"\n"/utf8>>))/binary>>/binary, "\n"/utf8>>/binary, Constructor/binary>>/binary, "\n}"/utf8>>. -file("src/atproto_codegen/emit.gleam", 250). -spec emit_encoder( atproto_codegen@config:config(), binary(), binary(), list(atproto_codegen@lexicon:property()), boolean() ) -> binary(). emit_encoder(Cfg, Nsid, Name, Props, Is_record) -> {Required, Optional} = gleam@list:partition( Props, fun(P) -> erlang:element(4, P) end ), Required_entries = gleam@list:map( Required, fun(P@1) -> <<<<<<<<<<<<"#(\""/utf8, (escape(erlang:element(2, P@1)))/binary>>/binary, "\", "/utf8>>/binary, (encoder_expr(Cfg, Nsid, erlang:element(3, P@1)))/binary>>/binary, "(value."/utf8>>/binary, (atproto_codegen@naming:field_name(erlang:element(2, P@1)))/binary>>/binary, "))"/utf8>> end ), Type_entry = case Is_record of true -> [<<<<"#(\"$type\", json.string(\""/utf8, (escape(Nsid))/binary>>/binary, "\"))"/utf8>>]; false -> [] end, Inline = <<<<"["/utf8, (gleam@string:join( lists:append([Type_entry, Required_entries]), <<", "/utf8>> ))/binary>>/binary, "]"/utf8>>, Optional_groups = gleam@list:map( Optional, fun(P@2) -> <<<<<<<<<<<<"internal.opt(\""/utf8, (escape(erlang:element(2, P@2)))/binary>>/binary, "\", value."/utf8>>/binary, (atproto_codegen@naming:field_name( erlang:element(2, P@2) ))/binary>>/binary, ", "/utf8>>/binary, (encoder_expr(Cfg, Nsid, erlang:element(3, P@2)))/binary>>/binary, ")"/utf8>> end ), Groups = gleam@string:join([Inline | Optional_groups], <<",\n "/utf8>>), <<<<<<<<<<<<"pub fn encode_"/utf8, (justin:snake_case(Name))/binary>>/binary, "(value: "/utf8>>/binary, Name/binary>>/binary, ") -> json.Json {\n json.object(list.flatten([\n "/utf8>>/binary, Groups/binary>>/binary, ",\n ]))\n}"/utf8>>. -file("src/atproto_codegen/emit.gleam", 221). -spec emit_type( atproto_codegen@config:config(), binary(), binary(), list(atproto_codegen@lexicon:property()) ) -> binary(). emit_type(Cfg, Nsid, Name, Props) -> case Props of [] -> <<<<<<<<"pub type "/utf8, Name/binary>>/binary, " {\n "/utf8>>/binary, Name/binary>>/binary, "\n}"/utf8>>; _ -> Fields = gleam@list:map( Props, fun(P) -> T = gleam_type(Cfg, Nsid, erlang:element(3, P)), T@1 = case erlang:element(4, P) of true -> T; false -> <<<<"Option("/utf8, T/binary>>/binary, ")"/utf8>> end, <<<<<<<<" "/utf8, (atproto_codegen@naming:field_name( erlang:element(2, P) ))/binary>>/binary, ": "/utf8>>/binary, T@1/binary>>/binary, ","/utf8>> end ), <<<<<<<<<<<<"pub type "/utf8, Name/binary>>/binary, " {\n "/utf8>>/binary, Name/binary>>/binary, "(\n"/utf8>>/binary, (gleam@string:join(Fields, <<"\n"/utf8>>))/binary>>/binary, "\n )\n}"/utf8>> end. -file("src/atproto_codegen/emit.gleam", 200). -spec emit_def( atproto_codegen@config:config(), binary(), atproto_codegen@lexicon:def() ) -> binary(). emit_def(Cfg, Nsid, Def) -> Name = atproto_codegen@naming:def_type_name(erlang:element(5, Cfg), Def), Props = def_properties(Def), Is_record = case Def of {record, _, _} -> true; _ -> false end, gleam@string:join(lists:append([case Is_record of true -> [<<<<"pub const collection = \""/utf8, (escape(Nsid))/binary>>/binary, "\""/utf8>>]; false -> [] end, [emit_type(Cfg, Nsid, Name, Props)], [emit_encoder( Cfg, Nsid, Name, Props, Is_record )], [emit_decoder(Cfg, Nsid, Name, Props)]]), <<"\n\n"/utf8>>). -file("src/atproto_codegen/emit.gleam", 116). -spec emit_lexicon( atproto_codegen@config:config(), atproto_codegen@lexicon:lexicon() ) -> gleam@option:option(binary()). emit_lexicon(Cfg, Lex) -> Emittable = gleam@list:filter(erlang:element(3, Lex), fun(D) -> case D of {record, _, _} -> true; {object, _, _, _} -> true; _ -> false end end), case Emittable of [] -> none; Defs -> Bodies = gleam@list:map( Defs, fun(_capture) -> emit_def(Cfg, erlang:element(2, Lex), _capture) end ), Header = emit_header(Cfg, erlang:element(2, Lex), Defs), {some, <<<<<<<<"//// Generated by codegen from lexicons/. Do not edit by hand.\n\n"/utf8, Header/binary>>/binary, "\n"/utf8>>/binary, (gleam@string:join(Bodies, <<"\n\n"/utf8>>))/binary>>/binary, "\n"/utf8>>} end.