-module(protozoa@internal@codegen@types). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/protozoa/internal/codegen/types.gleam"). -export([flatten_type_name/1, capitalize_first/1, generate_enum_type/1, generate_enum_types/1, escape_keyword/1, generate_message_types_with_registry_tracked/4, generate_types_with_registry/3]). -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). -file("src/protozoa/internal/codegen/types.gleam", 214). ?DOC(false). -spec has_deprecated_option(list(protozoa@parser:field_option())) -> boolean(). has_deprecated_option(Options) -> gleam@list:any(Options, fun(Option) -> case Option of {deprecated, true} -> true; _ -> false end end). -file("src/protozoa/internal/codegen/types.gleam", 338). ?DOC(false). -spec is_nested_type_in_message(binary(), protozoa@parser:message()) -> boolean(). is_nested_type_in_message(Type_name, Parent_message) -> _pipe = erlang:element(5, Parent_message), gleam@list:any( _pipe, fun(Nested) -> erlang:element(2, Nested) =:= Type_name end ). -file("src/protozoa/internal/codegen/types.gleam", 343). ?DOC(false). -spec is_nested_enum_in_message(binary(), protozoa@parser:message()) -> boolean(). is_nested_enum_in_message(Enum_name, Parent_message) -> _pipe = erlang:element(6, Parent_message), gleam@list:any( _pipe, fun(Nested_enum) -> erlang:element(2, Nested_enum) =:= Enum_name end ). -file("src/protozoa/internal/codegen/types.gleam", 316). ?DOC(false). -spec qualify_nested_field_type( protozoa@parser:proto_type(), binary(), protozoa@parser:message() ) -> protozoa@parser:proto_type(). qualify_nested_field_type(Proto_type, Parent_name, Parent_message) -> case Proto_type of {message_type, Name} -> case is_nested_type_in_message(Name, Parent_message) of true -> {message_type, <>}; false -> Proto_type end; {enum_type, Name@1} -> case is_nested_enum_in_message(Name@1, Parent_message) of true -> {enum_type, <>}; false -> Proto_type end; _ -> Proto_type end. -file("src/protozoa/internal/codegen/types.gleam", 223). ?DOC(false). -spec flatten_nested_message( protozoa@parser:message(), protozoa@parser:message() ) -> protozoa@parser:message(). flatten_nested_message(Nested_msg, Parent) -> Fixed_fields = begin _pipe = erlang:element(3, Nested_msg), gleam@list:map( _pipe, fun(Field) -> Updated_field_type = qualify_nested_field_type( erlang:element(3, Field), erlang:element(2, Parent), Parent ), {field, erlang:element(2, Field), Updated_field_type, erlang:element(4, Field), erlang:element(5, Field), erlang:element(6, Field)} end ) end, {message, <<(erlang:element(2, Parent))/binary, (erlang:element(2, Nested_msg))/binary>>, Fixed_fields, erlang:element(4, Nested_msg), erlang:element(5, Nested_msg), erlang:element(6, Nested_msg)}. -file("src/protozoa/internal/codegen/types.gleam", 394). ?DOC(false). -spec is_well_known_source(binary()) -> boolean(). is_well_known_source(Source_file) -> gleam_stdlib:string_starts_with(Source_file, <<"google/protobuf/"/utf8>>). -file("src/protozoa/internal/codegen/types.gleam", 418). ?DOC(false). -spec flatten_type_name(binary()) -> binary(). flatten_type_name(Name) -> case Name of <<"google.protobuf.Timestamp"/utf8>> -> <<"Timestamp"/utf8>>; <<"google.protobuf.Duration"/utf8>> -> <<"Duration"/utf8>>; <<"google.protobuf.FieldMask"/utf8>> -> <<"FieldMask"/utf8>>; <<"google.protobuf.Empty"/utf8>> -> <<"Empty"/utf8>>; <<"google.protobuf.Any"/utf8>> -> <<"Any"/utf8>>; <<"google.protobuf.Struct"/utf8>> -> <<"Struct"/utf8>>; <<"google.protobuf.Value"/utf8>> -> <<"Value"/utf8>>; <<"google.protobuf.ListValue"/utf8>> -> <<"ListValue"/utf8>>; <<"google.protobuf.NullValue"/utf8>> -> <<"NullValue"/utf8>>; <<"google.protobuf.DoubleValue"/utf8>> -> <<"DoubleValue"/utf8>>; <<"google.protobuf.FloatValue"/utf8>> -> <<"FloatValue"/utf8>>; <<"google.protobuf.Int64Value"/utf8>> -> <<"Int64Value"/utf8>>; <<"google.protobuf.UInt64Value"/utf8>> -> <<"UInt64Value"/utf8>>; <<"google.protobuf.Int32Value"/utf8>> -> <<"Int32Value"/utf8>>; <<"google.protobuf.UInt32Value"/utf8>> -> <<"UInt32Value"/utf8>>; <<"google.protobuf.BoolValue"/utf8>> -> <<"BoolValue"/utf8>>; <<"google.protobuf.StringValue"/utf8>> -> <<"StringValue"/utf8>>; <<"google.protobuf.BytesValue"/utf8>> -> <<"BytesValue"/utf8>>; _ -> _pipe = Name, gleam@string:replace(_pipe, <<"."/utf8>>, <<""/utf8>>) end. -file("src/protozoa/internal/codegen/types.gleam", 398). ?DOC(false). -spec qualify_cross_file_type(binary(), binary()) -> binary(). qualify_cross_file_type(Type_name, Source_file) -> Module_name = case gleam@string:split(Source_file, <<"/"/utf8>>) of [] -> <<"unknown"/utf8>>; Parts -> case gleam@list:last(Parts) of {ok, Filename} -> case gleam@string:split(Filename, <<"."/utf8>>) of [Name | _] -> Name; [] -> <<"unknown"/utf8>> end; {error, _} -> <<"unknown"/utf8>> end end, <<<>/binary, (flatten_type_name(Type_name))/binary>>. -file("src/protozoa/internal/codegen/types.gleam", 348). ?DOC(false). -spec resolve_external_type_simple( binary(), protozoa@internal@type_registry:type_registry(), binary() ) -> binary(). resolve_external_type_simple(Name, Registry, File_path) -> Current_package = case protozoa@internal@type_registry:get_file_package( Registry, File_path ) of {some, Pkg} -> Pkg; none -> <<""/utf8>> end, case protozoa@internal@type_registry:resolve_type_reference( Registry, Name, Current_package ) of {ok, Resolved_fqn} -> case protozoa@internal@type_registry:get_type_source( Registry, Resolved_fqn ) of {some, Source_file} -> case is_well_known_source(Source_file) of true -> flatten_type_name(Resolved_fqn); false -> case Source_file =:= File_path of true -> flatten_type_name(Name); false -> qualify_cross_file_type(Name, Source_file) end end; none -> flatten_type_name(Name) end; {error, _} -> case Name =:= <<"OtherMessage"/utf8>> of true -> <<"other."/utf8, (flatten_type_name(Name))/binary>>; false -> flatten_type_name(Name) end end. -file("src/protozoa/internal/codegen/types.gleam", 278). ?DOC(false). -spec resolve_field_type_simple( protozoa@parser:proto_type(), protozoa@internal@type_registry:type_registry(), binary() ) -> binary(). resolve_field_type_simple(Proto_type, Registry, File_path) -> case Proto_type of string -> <<"String"/utf8>>; int32 -> <<"Int"/utf8>>; int64 -> <<"Int"/utf8>>; u_int32 -> <<"Int"/utf8>>; u_int64 -> <<"Int"/utf8>>; s_int32 -> <<"Int"/utf8>>; s_int64 -> <<"Int"/utf8>>; fixed32 -> <<"Int"/utf8>>; fixed64 -> <<"Int"/utf8>>; s_fixed32 -> <<"Int"/utf8>>; s_fixed64 -> <<"Int"/utf8>>; bool -> <<"Bool"/utf8>>; bytes -> <<"BitArray"/utf8>>; double -> <<"Float"/utf8>>; float -> <<"Float"/utf8>>; {message_type, Name} -> resolve_external_type_simple(Name, Registry, File_path); {enum_type, Name@1} -> resolve_external_type_simple(Name@1, Registry, File_path); {repeated, Inner} -> <<<<"List("/utf8, (resolve_field_type_simple(Inner, Registry, File_path))/binary>>/binary, ")"/utf8>>; {optional, Inner@1} -> <<<<"Option("/utf8, (resolve_field_type_simple(Inner@1, Registry, File_path))/binary>>/binary, ")"/utf8>>; {map, Key, Value} -> <<<<<<<<"List(#("/utf8, (resolve_field_type_simple(Key, Registry, File_path))/binary>>/binary, ", "/utf8>>/binary, (resolve_field_type_simple(Value, Registry, File_path))/binary>>/binary, "))"/utf8>> end. -file("src/protozoa/internal/codegen/types.gleam", 263). ?DOC(false). -spec resolve_field_type( protozoa@parser:field(), protozoa@internal@type_registry:type_registry(), binary(), protozoa@parser:message() ) -> binary(). resolve_field_type(Field, Registry, File_path, _) -> case erlang:element(3, Field) of {repeated, Inner} -> <<<<"List("/utf8, (resolve_field_type_simple(Inner, Registry, File_path))/binary>>/binary, ")"/utf8>>; {optional, Inner@1} -> <<<<"Option("/utf8, (resolve_field_type_simple(Inner@1, Registry, File_path))/binary>>/binary, ")"/utf8>>; _ -> resolve_field_type_simple( erlang:element(3, Field), Registry, File_path ) end. -file("src/protozoa/internal/codegen/types.gleam", 447). ?DOC(false). -spec capitalize_first(binary()) -> binary(). capitalize_first(Str) -> _pipe = Str, _pipe@1 = gleam@string:split(_pipe, <<"_"/utf8>>), _pipe@2 = gleam@list:map( _pipe@1, fun(Part) -> case gleam_stdlib:string_pop_grapheme(Part) of {ok, {First, Rest}} -> <<(string:uppercase(First))/binary, Rest/binary>>; {error, _} -> Part end end ), gleam@string:join(_pipe@2, <<""/utf8>>). -file("src/protozoa/internal/codegen/types.gleam", 129). ?DOC(false). -spec generate_enum_type(protozoa@parser:enum()) -> binary(). generate_enum_type(Enum) -> Variants = begin _pipe = erlang:element(3, Enum), _pipe@1 = gleam@list:map( _pipe, fun(Variant) -> <<" "/utf8, (capitalize_first(erlang:element(2, Variant)))/binary>> end ), gleam@string:join(_pipe@1, <<"\n"/utf8>>) end, <<<<<<<<"pub type "/utf8, (erlang:element(2, Enum))/binary>>/binary, " {\n"/utf8>>/binary, Variants/binary>>/binary, "\n}"/utf8>>. -file("src/protozoa/internal/codegen/types.gleam", 122). ?DOC(false). -spec generate_enum_types(list(protozoa@parser:enum())) -> binary(). generate_enum_types(Enums) -> _pipe = Enums, _pipe@1 = gleam@list:map(_pipe, fun generate_enum_type/1), gleam@string:join(_pipe@1, <<"\n\n"/utf8>>). -file("src/protozoa/internal/codegen/types.gleam", 183). ?DOC(false). -spec generate_oneof_type( binary(), protozoa@parser:oneof(), protozoa@internal@type_registry:type_registry(), binary() ) -> binary(). generate_oneof_type(Message_name, Oneof, Registry, File_path) -> Type_name = <<(capitalize_first(Message_name))/binary, (capitalize_first(erlang:element(2, Oneof)))/binary>>, Variants = begin _pipe = erlang:element(3, Oneof), _pipe@1 = gleam@list:map( _pipe, fun(Field) -> Base_variant_name = capitalize_first(erlang:element(2, Field)), Gleam_type = resolve_field_type_simple( erlang:element(3, Field), Registry, File_path ), Variant_name = case {Base_variant_name, Gleam_type} of {<<"Empty"/utf8>>, <<"Empty"/utf8>>} -> <<"EmptyData"/utf8>>; {<<"StringValue"/utf8>>, <<"String"/utf8>>} -> <<"StringValueVariant"/utf8>>; {<<"BoolValue"/utf8>>, <<"Bool"/utf8>>} -> <<"BoolValueVariant"/utf8>>; {<<"ListValue"/utf8>>, <<"ListValue"/utf8>>} -> <<"ListValueVariant"/utf8>>; {Name, _} -> Name end, <<<<<<<<" "/utf8, Variant_name/binary>>/binary, "("/utf8>>/binary, Gleam_type/binary>>/binary, ")"/utf8>> end ), gleam@string:join(_pipe@1, <<"\n"/utf8>>) end, <<<<<<<<"pub type "/utf8, Type_name/binary>>/binary, " {\n"/utf8>>/binary, Variants/binary>>/binary, "\n}"/utf8>>. -file("src/protozoa/internal/codegen/types.gleam", 241). ?DOC(false). -spec generate_nested_enum_types( protozoa@parser:message(), gleam@set:set(binary()) ) -> {list(binary()), gleam@set:set(binary())}. generate_nested_enum_types(Message, Seen_enums) -> _pipe = erlang:element(6, Message), gleam@list:fold( _pipe, {[], Seen_enums}, fun(Acc, Nested_enum) -> {Existing_enum_types, Current_enums} = Acc, Flattened_name = <<(erlang:element(2, Message))/binary, (erlang:element(2, Nested_enum))/binary>>, case gleam@set:contains(Current_enums, Flattened_name) of true -> Acc; false -> Flattened_enum = {enum, Flattened_name, erlang:element(3, Nested_enum)}, Enum_code = generate_enum_type(Flattened_enum), Updated_enums = gleam@set:insert( Current_enums, Flattened_name ), {lists:append(Existing_enum_types, [Enum_code]), Updated_enums} end end ). -file("src/protozoa/internal/codegen/types.gleam", 45). ?DOC(false). -spec escape_keyword(binary()) -> binary(). escape_keyword(Name) -> case gleam@list:contains( [<<"case"/utf8>>, <<"const"/utf8>>, <<"fn"/utf8>>, <<"if"/utf8>>, <<"import"/utf8>>, <<"let"/utf8>>, <<"opaque"/utf8>>, <<"pub"/utf8>>, <<"todo"/utf8>>, <<"type"/utf8>>, <<"use"/utf8>>, <<"assert"/utf8>>, <<"try"/utf8>>, <<"panic"/utf8>>, <<"auto"/utf8>>, <<"delegate"/utf8>>, <<"derive"/utf8>>, <<"echo"/utf8>>, <<"else"/utf8>>, <<"external"/utf8>>, <<"macro"/utf8>>, <<"module"/utf8>>, <<"test"/utf8>>, <<"as"/utf8>>, <<"when"/utf8>>], Name ) of true -> <>; false -> Name end. -file("src/protozoa/internal/codegen/types.gleam", 139). ?DOC(false). -spec generate_message_type( protozoa@parser:message(), protozoa@internal@type_registry:type_registry(), binary() ) -> binary(). generate_message_type(Message, Registry, File_path) -> Fields = begin _pipe = erlang:element(3, Message), gleam@list:map( _pipe, fun(Field) -> Gleam_type = resolve_field_type( Field, Registry, File_path, Message ), Escaped_name = escape_keyword(erlang:element(2, Field)), Deprecation_comment = case has_deprecated_option( erlang:element(6, Field) ) of true -> <<" // @deprecated"/utf8>>; false -> <<""/utf8>> end, <<<<<<<<" "/utf8, Escaped_name/binary>>/binary, ": "/utf8>>/binary, Gleam_type/binary>>/binary, Deprecation_comment/binary>> end ) end, Oneofs = begin _pipe@1 = erlang:element(4, Message), gleam@list:map( _pipe@1, fun(Oneof) -> Oneof_type_name = <<(capitalize_first( erlang:element(2, Message) ))/binary, (capitalize_first(erlang:element(2, Oneof)))/binary>>, Escaped_name@1 = escape_keyword(erlang:element(2, Oneof)), <<<<<<<<" "/utf8, Escaped_name@1/binary>>/binary, ": option.Option("/utf8>>/binary, Oneof_type_name/binary>>/binary, ")"/utf8>> end ) end, All_fields = lists:append(Fields, Oneofs), case All_fields of [] -> <<<<<<<<"pub type "/utf8, (erlang:element(2, Message))/binary>>/binary, " {\n "/utf8>>/binary, (erlang:element(2, Message))/binary>>/binary, "\n}"/utf8>>; _ -> Fields_str = gleam@string:join(All_fields, <<",\n"/utf8>>), <<<<<<<<<<<<"pub type "/utf8, (erlang:element(2, Message))/binary>>/binary, " {\n "/utf8>>/binary, (erlang:element(2, Message))/binary>>/binary, "(\n"/utf8>>/binary, Fields_str/binary>>/binary, ",\n )\n}"/utf8>> end. -file("src/protozoa/internal/codegen/types.gleam", 78). ?DOC(false). -spec generate_message_types_with_registry_tracked( protozoa@parser:message(), protozoa@internal@type_registry:type_registry(), binary(), gleam@set:set(binary()) ) -> {list(binary()), gleam@set:set(binary())}. generate_message_types_with_registry_tracked( Message, Registry, File_path, Seen_enums ) -> {Nested_types, Enums_after_nested} = begin _pipe = erlang:element(5, Message), gleam@list:fold( _pipe, {[], Seen_enums}, fun(Acc, Nested_msg) -> {Existing_nested, Current_enums} = Acc, Flattened_msg = flatten_nested_message(Nested_msg, Message), {New_nested_types, Updated_enums} = generate_message_types_with_registry_tracked( Flattened_msg, Registry, File_path, Current_enums ), {lists:append(Existing_nested, New_nested_types), Updated_enums} end ) end, {Nested_enum_types, Enums_after_enum_gen} = generate_nested_enum_types( Message, Enums_after_nested ), Oneof_types = begin _pipe@1 = erlang:element(4, Message), gleam@list:map( _pipe@1, fun(Oneof) -> generate_oneof_type( erlang:element(2, Message), Oneof, Registry, File_path ) end ) end, Main_type = generate_message_type(Message, Registry, File_path), All_types = lists:append( [Nested_types, Nested_enum_types, Oneof_types, [Main_type]] ), {All_types, Enums_after_enum_gen}. -file("src/protozoa/internal/codegen/types.gleam", 53). ?DOC(false). -spec generate_types_with_registry( list(protozoa@parser:message()), protozoa@internal@type_registry:type_registry(), binary() ) -> binary(). generate_types_with_registry(Messages, Registry, File_path) -> Generated_enum_names = gleam@set:new(), {All_types, _} = begin _pipe = Messages, gleam@list:fold( _pipe, {[], Generated_enum_names}, fun(Acc, Msg) -> {Existing_types, Seen_enums} = Acc, {New_types, Updated_enums} = generate_message_types_with_registry_tracked( Msg, Registry, File_path, Seen_enums ), {lists:append(Existing_types, New_types), Updated_enums} end ) end, _pipe@1 = All_types, gleam@string:join(_pipe@1, <<"\n\n"/utf8>>).