Packages

A Protocol Buffers library for Gleam, providing encoding and decoding of protobuf messages.

Current section

Files

Jump to
protozoa src protozoa@internal@codegen.erl
Raw

src/protozoa@internal@codegen.erl

-module(protozoa@internal@codegen).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/protozoa/internal/codegen.gleam").
-export([is_well_known_type/1, generate_combined_proto_file/3, generate_well_known_type_definition/1, generate_simple_for_testing/1, generate_with_imports/3]).
-export_type([content_sections/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).
-type content_sections() :: {content_sections,
binary(),
binary(),
binary(),
binary(),
binary(),
binary()}.
-file("src/protozoa/internal/codegen.gleam", 172).
?DOC(false).
-spec get_base_name(binary()) -> binary().
get_base_name(File_path) ->
_pipe = File_path,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
_pipe@2 = gleam@list:last(_pipe@1),
_pipe@3 = gleam@result:unwrap(_pipe@2, <<""/utf8>>),
_pipe@4 = gleam@string:split(_pipe@3, <<"."/utf8>>),
_pipe@5 = gleam@list:first(_pipe@4),
gleam@result:unwrap(_pipe@5, <<"generated"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 182).
?DOC(false).
-spec generate_combined_file_header(list(protozoa@parser:path())) -> binary().
generate_combined_file_header(Files) ->
File_list = begin
_pipe = Files,
_pipe@1 = gleam@list:map(
_pipe,
fun(File) -> erlang:element(2, File) end
),
gleam@string:join(_pipe@1, <<", "/utf8>>)
end,
<<<<<<<<<<<<<<"//// Generated by Protozoa from "/utf8, File_list/binary>>/binary,
"\n"/utf8>>/binary,
"//// \n"/utf8>>/binary,
"//// This file is auto-generated and can be safely deleted and regenerated.\n"/utf8>>/binary,
"//// To regenerate all proto files, run: gleam run -m protozoa\n"/utf8>>/binary,
"//// \n"/utf8>>/binary,
"//// DO NOT EDIT THIS FILE MANUALLY - all changes will be lost on regeneration."/utf8>>.
-file("src/protozoa/internal/codegen.gleam", 294).
?DOC(false).
-spec combine_non_empty(binary(), binary()) -> binary().
combine_non_empty(Left, Right) ->
case {gleam@string:is_empty(Left), gleam@string:is_empty(Right)} of
{true, true} ->
<<""/utf8>>;
{true, false} ->
Right;
{false, true} ->
Left;
{false, false} ->
<<<<Left/binary, "\n\n"/utf8>>/binary, Right/binary>>
end.
-file("src/protozoa/internal/codegen.gleam", 263).
?DOC(false).
-spec combine_content_sections(list(content_sections())) -> content_sections().
combine_content_sections(All_sections) ->
gleam@list:fold(
All_sections,
{content_sections,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>,
<<""/utf8>>},
fun(Acc, Section) ->
{content_sections,
combine_non_empty(
erlang:element(2, Acc),
erlang:element(2, Section)
),
combine_non_empty(
erlang:element(3, Acc),
erlang:element(3, Section)
),
combine_non_empty(
erlang:element(4, Acc),
erlang:element(4, Section)
),
combine_non_empty(
erlang:element(5, Acc),
erlang:element(5, Section)
),
combine_non_empty(
erlang:element(6, Acc),
erlang:element(6, Section)
),
combine_non_empty(
erlang:element(7, Acc),
erlang:element(7, Section)
)}
end
).
-file("src/protozoa/internal/codegen.gleam", 303).
?DOC(false).
-spec is_well_known_proto_file(binary()) -> boolean().
is_well_known_proto_file(File_path) ->
gleam_stdlib:contains_string(File_path, <<"google/protobuf/"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 307).
?DOC(false).
-spec generate_file_header(binary()) -> binary().
generate_file_header(Proto_file_path) ->
<<<<<<<<<<<<<<"//// Generated by Protozoa from "/utf8,
Proto_file_path/binary>>/binary,
"\n"/utf8>>/binary,
"//// \n"/utf8>>/binary,
"//// This file is auto-generated and can be safely deleted and regenerated.\n"/utf8>>/binary,
"//// To regenerate all proto files, run: gleam run -m protozoa\n"/utf8>>/binary,
"//// \n"/utf8>>/binary,
"//// DO NOT EDIT THIS FILE MANUALLY - all changes will be lost on regeneration."/utf8>>.
-file("src/protozoa/internal/codegen.gleam", 384).
?DOC(false).
-spec has_repeated_fields(protozoa@parser:proto_file()) -> boolean().
has_repeated_fields(Proto_file) ->
_pipe = erlang:element(5, Proto_file),
gleam@list:any(_pipe, fun(Msg) -> _pipe@1 = erlang:element(3, Msg),
gleam@list:any(
_pipe@1,
fun(Field) -> case erlang:element(3, Field) of
{repeated, _} ->
true;
_ ->
false
end end
) end).
-file("src/protozoa/internal/codegen.gleam", 402).
?DOC(false).
-spec has_oneofs(protozoa@parser:proto_file()) -> boolean().
has_oneofs(Proto_file) ->
_pipe = erlang:element(5, Proto_file),
gleam@list:any(
_pipe,
fun(Msg) -> not gleam@list:is_empty(erlang:element(4, Msg)) end
).
-file("src/protozoa/internal/codegen.gleam", 407).
?DOC(false).
-spec has_optional_fields(protozoa@parser:proto_file()) -> boolean().
has_optional_fields(Proto_file) ->
_pipe = erlang:element(5, Proto_file),
gleam@list:any(_pipe, fun(Msg) -> _pipe@1 = erlang:element(3, Msg),
gleam@list:any(
_pipe@1,
fun(Field) -> case erlang:element(3, Field) of
{optional, _} ->
true;
_ ->
false
end end
) end).
-file("src/protozoa/internal/codegen.gleam", 420).
?DOC(false).
-spec has_enums(protozoa@parser:proto_file()) -> boolean().
has_enums(Proto_file) ->
not gleam@list:is_empty(erlang:element(6, Proto_file)) orelse begin
_pipe = erlang:element(5, Proto_file),
gleam@list:any(
_pipe,
fun(Msg) -> not gleam@list:is_empty(erlang:element(6, Msg)) end
)
end.
-file("src/protozoa/internal/codegen.gleam", 426).
?DOC(false).
-spec has_enum_fields(protozoa@parser:proto_file()) -> boolean().
has_enum_fields(Proto_file) ->
_pipe = erlang:element(5, Proto_file),
gleam@list:any(_pipe, fun(Msg) -> _pipe@1 = erlang:element(3, Msg),
gleam@list:any(
_pipe@1,
fun(Field) -> case erlang:element(3, Field) of
{enum_type, _} ->
true;
{repeated, {enum_type, _}} ->
true;
{optional, {enum_type, _}} ->
true;
_ ->
false
end end
) end).
-file("src/protozoa/internal/codegen.gleam", 441).
?DOC(false).
-spec has_bytes_fields(protozoa@parser:proto_file()) -> boolean().
has_bytes_fields(Proto_file) ->
_pipe = erlang:element(5, Proto_file),
gleam@list:any(_pipe, fun(Msg) -> _pipe@1 = erlang:element(3, Msg),
gleam@list:any(
_pipe@1,
fun(Field) -> case erlang:element(3, Field) of
bytes ->
true;
{repeated, bytes} ->
true;
{optional, bytes} ->
true;
_ ->
false
end end
) end).
-file("src/protozoa/internal/codegen.gleam", 456).
?DOC(false).
-spec has_message_fields(protozoa@parser:proto_file()) -> boolean().
has_message_fields(Proto_file) ->
_pipe = erlang:element(5, Proto_file),
gleam@list:any(
_pipe,
fun(Msg) ->
begin
_pipe@1 = erlang:element(3, Msg),
gleam@list:any(
_pipe@1,
fun(Field) -> case erlang:element(3, Field) of
{message_type, _} ->
true;
{repeated, {message_type, _}} ->
true;
{optional, {message_type, _}} ->
true;
_ ->
false
end end
)
end
orelse gleam@list:any(
erlang:element(4, Msg),
fun(Oneof) ->
gleam@list:any(
erlang:element(3, Oneof),
fun(Field@1) -> case erlang:element(3, Field@1) of
{message_type, _} ->
true;
_ ->
false
end end
)
end
)
end
).
-file("src/protozoa/internal/codegen.gleam", 545).
?DOC(false).
-spec is_well_known_type(binary()) -> boolean().
is_well_known_type(Type_name) ->
case Type_name of
<<"google.protobuf.Timestamp"/utf8>> ->
true;
<<"google.protobuf.Duration"/utf8>> ->
true;
<<"google.protobuf.FieldMask"/utf8>> ->
true;
<<"google.protobuf.Empty"/utf8>> ->
true;
<<"google.protobuf.Any"/utf8>> ->
true;
<<"google.protobuf.Struct"/utf8>> ->
true;
<<"google.protobuf.StringValue"/utf8>> ->
true;
<<"google.protobuf.Type"/utf8>> ->
true;
<<"google.protobuf.Field"/utf8>> ->
true;
<<"google.protobuf.Enum"/utf8>> ->
true;
<<"google.protobuf.EnumValue"/utf8>> ->
true;
<<"google.protobuf.Option"/utf8>> ->
true;
<<"google.protobuf.SourceContext"/utf8>> ->
true;
<<"google.protobuf.Api"/utf8>> ->
true;
<<"google.protobuf.Method"/utf8>> ->
true;
<<"google.protobuf.Mixin"/utf8>> ->
true;
<<"Timestamp"/utf8>> ->
true;
<<"Duration"/utf8>> ->
true;
<<"FieldMask"/utf8>> ->
true;
<<"Empty"/utf8>> ->
true;
<<"Any"/utf8>> ->
true;
<<"Struct"/utf8>> ->
true;
<<"StringValue"/utf8>> ->
true;
<<"Type"/utf8>> ->
true;
<<"Field"/utf8>> ->
true;
<<"Enum"/utf8>> ->
true;
<<"EnumValue"/utf8>> ->
true;
<<"Option"/utf8>> ->
true;
<<"SourceContext"/utf8>> ->
true;
<<"Api"/utf8>> ->
true;
<<"Method"/utf8>> ->
true;
<<"Mixin"/utf8>> ->
true;
_ ->
false
end.
-file("src/protozoa/internal/codegen.gleam", 502).
?DOC(false).
-spec get_field_well_known_types(protozoa@parser:message()) -> list(binary()).
get_field_well_known_types(Message) ->
Field_types = begin
_pipe = erlang:element(3, Message),
gleam@list:fold(
_pipe,
[],
fun(Acc, Field) -> case erlang:element(3, Field) of
{message_type, Name} ->
case is_well_known_type(Name) of
true ->
[Name | Acc];
false ->
Acc
end;
{repeated, {message_type, Name@1}} ->
case is_well_known_type(Name@1) of
true ->
[Name@1 | Acc];
false ->
Acc
end;
{optional, {message_type, Name@2}} ->
case is_well_known_type(Name@2) of
true ->
[Name@2 | Acc];
false ->
Acc
end;
_ ->
Acc
end end
)
end,
Oneof_types = begin
_pipe@1 = erlang:element(4, Message),
gleam@list:fold(
_pipe@1,
[],
fun(Acc@1, Oneof) -> _pipe@2 = erlang:element(3, Oneof),
gleam@list:fold(
_pipe@2,
Acc@1,
fun(Acc2, Field@1) -> case erlang:element(3, Field@1) of
{message_type, Name@3} ->
case is_well_known_type(Name@3) of
true ->
[Name@3 | Acc2];
false ->
Acc2
end;
_ ->
Acc2
end end
) end
)
end,
lists:append(Field_types, Oneof_types).
-file("src/protozoa/internal/codegen.gleam", 492).
?DOC(false).
-spec get_referenced_well_known_types(protozoa@parser:proto_file()) -> list(binary()).
get_referenced_well_known_types(Proto_file) ->
_pipe = erlang:element(5, Proto_file),
_pipe@1 = gleam@list:fold(
_pipe,
[],
fun(Acc, Message) ->
Field_types = get_field_well_known_types(Message),
lists:append(Acc, Field_types)
end
),
gleam@list:unique(_pipe@1).
-file("src/protozoa/internal/codegen.gleam", 397).
?DOC(false).
-spec has_field_mask_reference(protozoa@parser:proto_file()) -> boolean().
has_field_mask_reference(Proto_file) ->
_pipe = get_referenced_well_known_types(Proto_file),
gleam@list:contains(_pipe, <<"google.protobuf.FieldMask"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 324).
?DOC(false).
-spec determine_needed_imports(protozoa@parser:proto_file()) -> list(binary()).
determine_needed_imports(Proto_file) ->
Base_imports = [<<"import protozoa/decode"/utf8>>,
<<"import protozoa/encode"/utf8>>],
Needs_list = has_repeated_fields(Proto_file) orelse has_field_mask_reference(
Proto_file
),
Imports = case Needs_list of
true ->
[<<"import gleam/list"/utf8>> | Base_imports];
false ->
Base_imports
end,
Has_optional = has_optional_fields(Proto_file),
Has_oneof = has_oneofs(Proto_file),
Imports@1 = case {Has_optional, Has_oneof} of
{true, true} ->
[<<"import gleam/option.{type Option, None, Some}"/utf8>> | Imports];
{true, false} ->
[<<"import gleam/option.{type Option, None, Some}"/utf8>> | Imports];
{false, true} ->
[<<"import gleam/option.{None, Some}"/utf8>> | Imports];
{false, false} ->
Imports
end,
Needs_dict = has_oneofs(Proto_file),
Imports@2 = case Needs_dict of
true ->
[<<"import gleam/dict"/utf8>> | Imports@1];
false ->
Imports@1
end,
Needs_result = has_enums(Proto_file) orelse has_enum_fields(Proto_file),
Imports@3 = case Needs_result of
true ->
[<<"import gleam/result"/utf8>> | Imports@2];
false ->
Imports@2
end,
Needs_string = has_enums(Proto_file) orelse has_enum_fields(Proto_file),
Imports@4 = case Needs_string of
true ->
[<<"import gleam/string"/utf8>> | Imports@3];
false ->
Imports@3
end,
Needs_int = has_enums(Proto_file) orelse has_enum_fields(Proto_file),
Imports@5 = case Needs_int of
true ->
[<<"import gleam/int"/utf8>> | Imports@4];
false ->
Imports@4
end,
Needs_wire = has_bytes_fields(Proto_file) orelse has_message_fields(
Proto_file
),
Imports@6 = case Needs_wire of
true ->
[<<"import protozoa/wire"/utf8>> | Imports@5];
false ->
Imports@5
end,
gleam@list:sort(Imports@6, fun gleam@string:compare/2).
-file("src/protozoa/internal/codegen.gleam", 198).
?DOC(false).
-spec generate_combined_imports(
list(protozoa@parser:path()),
protozoa@internal@type_registry:type_registry()
) -> binary().
generate_combined_imports(Files, _) ->
All_needed_imports = begin
_pipe = Files,
_pipe@1 = gleam@list:fold(
_pipe,
[],
fun(Acc, File) ->
File_imports = determine_needed_imports(erlang:element(3, File)),
lists:append(Acc, File_imports)
end
),
_pipe@2 = gleam@list:unique(_pipe@1),
gleam@list:sort(_pipe@2, fun gleam@string:compare/2)
end,
gleam@string:join(All_needed_imports, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 318).
?DOC(false).
-spec generate_imports(protozoa@parser:proto_file()) -> binary().
generate_imports(Proto_file) ->
Needed_imports = determine_needed_imports(Proto_file),
_pipe = Needed_imports,
gleam@string:join(_pipe, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 610).
?DOC(false).
-spec generate_timestamp_definition() -> binary().
generate_timestamp_definition() ->
Lines = [<<"pub type Timestamp {"/utf8>>,
<<" Timestamp("/utf8>>,
<<" seconds: Int,"/utf8>>,
<<" nanos: Int,"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_timestamp(timestamp: Timestamp) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.int64_field(1, timestamp.seconds),"/utf8>>,
<<" encode.int32_field(2, timestamp.nanos),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn timestamp_decoder() -> decode.Decoder(Timestamp) {"/utf8>>,
<<" use seconds <- decode.then(decode.int64_with_default(1, 0))"/utf8>>,
<<" use nanos <- decode.then(decode.int32_with_default(2, 0))"/utf8>>,
<<" decode.success(Timestamp(seconds: seconds, nanos: nanos))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 635).
?DOC(false).
-spec generate_duration_definition() -> binary().
generate_duration_definition() ->
Lines = [<<"pub type Duration {"/utf8>>,
<<" Duration("/utf8>>,
<<" seconds: Int,"/utf8>>,
<<" nanos: Int,"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_duration(duration: Duration) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.int64_field(1, duration.seconds),"/utf8>>,
<<" encode.int32_field(2, duration.nanos),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn duration_decoder() -> decode.Decoder(Duration) {"/utf8>>,
<<" use seconds <- decode.then(decode.int64_with_default(1, 0))"/utf8>>,
<<" use nanos <- decode.then(decode.int32_with_default(2, 0))"/utf8>>,
<<" decode.success(Duration(seconds: seconds, nanos: nanos))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 660).
?DOC(false).
-spec generate_fieldmask_definition() -> binary().
generate_fieldmask_definition() ->
Lines = [<<"pub type FieldMask {"/utf8>>,
<<" FieldMask("/utf8>>,
<<" paths: List(String),"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_fieldmask(fieldmask: FieldMask) -> BitArray {"/utf8>>,
<<" let paths_fields = list.map(fieldmask.paths, fn(v) { encode.string_field(1, v) })"/utf8>>,
<<" encode.message(paths_fields)"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn fieldmask_decoder() -> decode.Decoder(FieldMask) {"/utf8>>,
<<" use paths <- decode.then(decode.repeated_string(1))"/utf8>>,
<<" decode.success(FieldMask(paths: paths))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 681).
?DOC(false).
-spec generate_empty_definition() -> binary().
generate_empty_definition() ->
Lines = [<<"pub type Empty {"/utf8>>,
<<" Empty"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_empty(_empty: Empty) -> BitArray {"/utf8>>,
<<" encode.message([])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn empty_decoder() -> decode.Decoder(Empty) {"/utf8>>,
<<" decode.success(Empty)"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 698).
?DOC(false).
-spec generate_any_definition() -> binary().
generate_any_definition() ->
Lines = [<<"pub type Any {"/utf8>>,
<<" Any("/utf8>>,
<<" type_url: String,"/utf8>>,
<<" value: BitArray,"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_any(any: Any) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.string_field(1, any.type_url),"/utf8>>,
<<" encode.field(2, wire.LengthDelimited, encode.length_delimited(any.value)),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn any_decoder() -> decode.Decoder(Any) {"/utf8>>,
<<" use type_url <- decode.then(decode.string_with_default(1, \"\"))"/utf8>>,
<<" use value <- decode.then(decode.bytes(2))"/utf8>>,
<<" decode.success(Any(type_url: type_url, value: value))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 723).
?DOC(false).
-spec generate_struct_definition() -> binary().
generate_struct_definition() ->
Lines = [<<"pub type NullValue {"/utf8>>,
<<" NULL_VALUE"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub type Value {"/utf8>>,
<<" NullValueVariant(NullValue)"/utf8>>,
<<" NumberValueVariant(Float)"/utf8>>,
<<" StringValueVariant(String)"/utf8>>,
<<" BoolValueVariant(Bool)"/utf8>>,
<<" StructValueVariant(Struct)"/utf8>>,
<<" ListValueVariant(ListValue)"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub type ListValue {"/utf8>>,
<<" ListValue(values: List(Value))"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub type Struct {"/utf8>>,
<<" Struct(fields: dict.Dict(String, Value))"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_struct(struct: Struct) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.field(1, wire.LengthDelimited, encode_struct_fields_map(struct.fields)),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"fn encode_struct_fields_map(fields: dict.Dict(String, Value)) -> BitArray {"/utf8>>,
<<" // Simplified implementation - encode as repeated fields"/utf8>>,
<<" encode.length_delimited(<<>>)"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn struct_decoder() -> decode.Decoder(Struct) {"/utf8>>,
<<" // Simplified implementation - return empty struct"/utf8>>,
<<" decode.success(Struct(fields: dict.new()))"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"fn encode_value(value: Value) -> BitArray {"/utf8>>,
<<" case value {"/utf8>>,
<<" NullValueVariant(_) -> encode.message([encode.enum_field(1, 0)])"/utf8>>,
<<" NumberValueVariant(n) -> encode.message([encode.double_field(2, n)])"/utf8>>,
<<" StringValueVariant(s) -> encode.message([encode.string_field(3, s)])"/utf8>>,
<<" BoolValueVariant(b) -> encode.message([encode.bool_field(4, b)])"/utf8>>,
<<" StructValueVariant(s) -> encode.message([encode.field(5, wire.LengthDelimited, encode_struct(s))])"/utf8>>,
<<" ListValueVariant(l) -> encode.message([encode.field(6, wire.LengthDelimited, encode_listvalue(l))])"/utf8>>,
<<" }"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_listvalue(listvalue: ListValue) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.repeated_field(1, listvalue.values, encode_value),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn value_decoder() -> decode.Decoder(Value) {"/utf8>>,
<<" // Simplified implementation - default to null value"/utf8>>,
<<" decode.success(NullValueVariant(NULL_VALUE))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 787).
?DOC(false).
-spec generate_stringvalue_definition() -> binary().
generate_stringvalue_definition() ->
Lines = [<<"pub type StringValue {"/utf8>>,
<<" StringValue(value: String)"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_stringvalue(stringvalue: StringValue) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.string_field(1, stringvalue.value),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn stringvalue_decoder() -> decode.Decoder(StringValue) {"/utf8>>,
<<" use value <- decode.then(decode.string_with_default(1, \"\"))"/utf8>>,
<<" decode.success(StringValue(value: value))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 914).
?DOC(false).
-spec get_streaming_comment(boolean(), boolean(), binary()) -> binary().
get_streaming_comment(Client_streaming, Server_streaming, Interface_type) ->
Base_type = case Interface_type of
<<"server"/utf8>> ->
<<"// "/utf8, (case {Client_streaming, Server_streaming} of
{false, false} ->
<<"Unary handler"/utf8>>;
{false, true} ->
<<"Server streaming handler"/utf8>>;
{true, false} ->
<<"Client streaming handler"/utf8>>;
{true, true} ->
<<"Bidirectional streaming handler"/utf8>>
end)/binary>>;
_ ->
<<"// "/utf8, (case {Client_streaming, Server_streaming} of
{false, false} ->
<<"Unary call"/utf8>>;
{false, true} ->
<<"Server streaming"/utf8>>;
{true, false} ->
<<"Client streaming"/utf8>>;
{true, true} ->
<<"Bidirectional streaming"/utf8>>
end)/binary>>
end,
Base_type.
-file("src/protozoa/internal/codegen.gleam", 882).
?DOC(false).
-spec generate_method_comments(list(protozoa@parser:method()), binary()) -> binary().
generate_method_comments(Methods, Interface_type) ->
Comment_prefix = case Interface_type of
<<"client"/utf8>> ->
<<<<"// Method signatures for "/utf8, Interface_type/binary>>/binary,
":"/utf8>>;
<<"server"/utf8>> ->
<<<<"// Method signatures for "/utf8, Interface_type/binary>>/binary,
":"/utf8>>;
_ ->
<<"// Method signatures:"/utf8>>
end,
Method_lines = gleam@list:map(
Methods,
fun(Method) ->
Streaming_info = get_streaming_comment(
erlang:element(5, Method),
erlang:element(6, Method),
Interface_type
),
<<<<<<<<<<<<<<" // "/utf8, (erlang:element(2, Method))/binary>>/binary,
"("/utf8>>/binary,
(erlang:element(3, Method))/binary>>/binary,
") -> "/utf8>>/binary,
(erlang:element(4, Method))/binary>>/binary,
" "/utf8>>/binary,
Streaming_info/binary>>
end
),
gleam@string:join([Comment_prefix | Method_lines], <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 837).
?DOC(false).
-spec generate_client_interface(protozoa@parser:service()) -> binary().
generate_client_interface(Service) ->
Type_name = <<(erlang:element(2, Service))/binary, "Client"/utf8>>,
Method_comments = generate_method_comments(
erlang:element(3, Service),
<<"client"/utf8>>
),
gleam@string:join(
[<<<<"/// Client interface for "/utf8,
(erlang:element(2, Service))/binary>>/binary,
" service"/utf8>>,
<<"/// This trait defines the client-side methods for calling the service"/utf8>>,
<<<<"pub type "/utf8, Type_name/binary>>/binary, " {"/utf8>>,
<<<<" "/utf8, Type_name/binary>>/binary, "("/utf8>>,
<<" // TODO: Add client implementation fields (e.g., HTTP client, endpoint URL)"/utf8>>,
<<" endpoint: String,"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
Method_comments,
<<"// TODO: Implement actual client method calls"/utf8>>],
<<"\n"/utf8>>
).
-file("src/protozoa/internal/codegen.gleam", 860).
?DOC(false).
-spec generate_server_interface(protozoa@parser:service()) -> binary().
generate_server_interface(Service) ->
Type_name = <<(erlang:element(2, Service))/binary, "Server"/utf8>>,
Method_comments = generate_method_comments(
erlang:element(3, Service),
<<"server"/utf8>>
),
gleam@string:join(
[<<<<"/// Server interface for "/utf8,
(erlang:element(2, Service))/binary>>/binary,
" service"/utf8>>,
<<"/// Implement this trait to handle incoming service requests"/utf8>>,
<<<<"pub type "/utf8, Type_name/binary>>/binary, " {"/utf8>>,
<<<<" "/utf8, Type_name/binary>>/binary, "("/utf8>>,
<<" // TODO: Add server implementation fields"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
Method_comments,
<<"// TODO: Implement server method handlers and request routing"/utf8>>],
<<"\n"/utf8>>
).
-file("src/protozoa/internal/codegen.gleam", 820).
?DOC(false).
-spec generate_single_service_stub(protozoa@parser:service()) -> binary().
generate_single_service_stub(Service) ->
Client_interface = generate_client_interface(Service),
Server_interface = generate_server_interface(Service),
gleam@string:join(
[<<"// Service: "/utf8, (erlang:element(2, Service))/binary>>,
<<""/utf8>>,
Client_interface,
<<""/utf8>>,
Server_interface],
<<"\n"/utf8>>
).
-file("src/protozoa/internal/codegen.gleam", 808).
?DOC(false).
-spec generate_service_stubs(list(protozoa@parser:service())) -> binary().
generate_service_stubs(Services) ->
case Services of
[] ->
<<""/utf8>>;
_ ->
_pipe = Services,
_pipe@1 = gleam@list:map(_pipe, fun generate_single_service_stub/1),
gleam@string:join(_pipe@1, <<"\n\n"/utf8>>)
end.
-file("src/protozoa/internal/codegen.gleam", 226).
?DOC(false).
-spec generate_file_content_sections(
protozoa@parser:proto_file(),
binary(),
protozoa@internal@type_registry:type_registry()
) -> {ok, content_sections()} | {error, binary()}.
generate_file_content_sections(Proto_file, File_path, Registry) ->
Enum_types = protozoa@internal@codegen@types:generate_enum_types(
erlang:element(6, Proto_file)
),
Message_types = protozoa@internal@codegen@types:generate_types_with_registry(
erlang:element(5, Proto_file),
Registry,
File_path
),
Message_encoders = protozoa@internal@codegen@encoders:generate_encoders_with_registry(
erlang:element(5, Proto_file),
Registry,
File_path
),
Message_decoders = protozoa@internal@codegen@decoders:generate_decoders_with_registry(
erlang:element(5, Proto_file),
Registry,
File_path
),
Enum_helpers = protozoa@internal@codegen@encoders:generate_enum_helpers_with_nested(
erlang:element(6, Proto_file),
erlang:element(5, Proto_file)
),
Service_stubs = generate_service_stubs(erlang:element(7, Proto_file)),
{ok,
{content_sections,
Enum_types,
Message_types,
Message_encoders,
Message_decoders,
Enum_helpers,
Service_stubs}}.
-file("src/protozoa/internal/codegen.gleam", 53).
?DOC(false).
-spec generate_combined_proto_file(
list(protozoa@parser:path()),
protozoa@internal@type_registry:type_registry(),
binary()
) -> {ok, list({binary(), binary()})} | {error, binary()}.
generate_combined_proto_file(Files, Registry, Output_dir) ->
Output_path = <<Output_dir/binary, "/proto.gleam"/utf8>>,
User_files = gleam@list:filter(
Files,
fun(File) -> not is_well_known_proto_file(erlang:element(2, File)) end
),
Well_known_files = gleam@list:filter(
Files,
fun(File@1) -> is_well_known_proto_file(erlang:element(2, File@1)) end
),
Combined_header = generate_combined_file_header(User_files),
Combined_imports = generate_combined_imports(Files, Registry),
gleam@result:'try'(
gleam@list:try_map(
User_files,
fun(File_entry) ->
generate_file_content_sections(
erlang:element(3, File_entry),
erlang:element(2, File_entry),
Registry
)
end
),
fun(User_sections) ->
gleam@result:'try'(
gleam@list:try_map(
Well_known_files,
fun(File_entry@1) ->
generate_file_content_sections(
erlang:element(3, File_entry@1),
erlang:element(2, File_entry@1),
Registry
)
end
),
fun(Well_known_sections) ->
All_sections = lists:append(
User_sections,
Well_known_sections
),
Combined_sections = combine_content_sections(All_sections),
Final_code = gleam@string:join(
begin
_pipe = [Combined_header,
Combined_imports,
erlang:element(2, Combined_sections),
erlang:element(3, Combined_sections),
erlang:element(4, Combined_sections),
erlang:element(5, Combined_sections),
erlang:element(6, Combined_sections),
erlang:element(7, Combined_sections)],
gleam@list:filter(
_pipe,
fun(Section) ->
not gleam@string:is_empty(Section)
end
)
end,
<<"\n\n"/utf8>>
),
gleam@result:'try'(
begin
_pipe@1 = simplifile:write(Output_path, Final_code),
gleam@result:map_error(
_pipe@1,
fun(_) ->
<<"Failed to write file: "/utf8,
Output_path/binary>>
end
)
end,
fun(_) -> {ok, [{Output_path, Final_code}]} end
)
end
)
end
).
-file("src/protozoa/internal/codegen.gleam", 942).
?DOC(false).
-spec generate_type_definition() -> binary().
generate_type_definition() ->
Lines = [<<"pub type Syntax {"/utf8>>,
<<" SYNTAX_PROTO2"/utf8>>,
<<" SYNTAX_PROTO3"/utf8>>,
<<" SYNTAX_EDITIONS"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub type Type {"/utf8>>,
<<" Type("/utf8>>,
<<" name: String,"/utf8>>,
<<" fields: List(Field),"/utf8>>,
<<" oneofs: List(String),"/utf8>>,
<<" options: List(Option),"/utf8>>,
<<" source_context: option.Option(SourceContext),"/utf8>>,
<<" syntax: Syntax,"/utf8>>,
<<" edition: String,"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_type(type_def: Type) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.string_field(1, type_def.name),"/utf8>>,
<<" // Simplified: skip complex nested fields for now"/utf8>>,
<<" encode.enum_field(6, encode_syntax_value(type_def.syntax)),"/utf8>>,
<<" encode.string_field(7, type_def.edition),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn type_decoder() -> decode.Decoder(Type) {"/utf8>>,
<<" use name <- decode.then(decode.string_with_default(1, \"\"))"/utf8>>,
<<" use fields <- decode.then(decode.repeated_field(2, fn(_) { Ok([]) }))"/utf8>>,
<<" use oneofs <- decode.then(decode.repeated_string(3))"/utf8>>,
<<" use options <- decode.then(decode.repeated_field(4, fn(_) { Ok([]) }))"/utf8>>,
<<" use source_context <- decode.then(decode.optional_nested_message(5, sourcecontext_decoder()))"/utf8>>,
<<" use syntax <- decode.then(decode.enum_field(6, decode_syntax_field()))"/utf8>>,
<<" use edition <- decode.then(decode.string_with_default(7, \"\"))"/utf8>>,
<<" decode.success(Type("/utf8>>,
<<" name: name,"/utf8>>,
<<" fields: fields,"/utf8>>,
<<" oneofs: oneofs,"/utf8>>,
<<" options: options,"/utf8>>,
<<" source_context: source_context,"/utf8>>,
<<" syntax: syntax,"/utf8>>,
<<" edition: edition,"/utf8>>,
<<" ))"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"fn encode_syntax_value(syntax: Syntax) -> Int {"/utf8>>,
<<" case syntax {"/utf8>>,
<<" SYNTAX_PROTO2 -> 0"/utf8>>,
<<" SYNTAX_PROTO3 -> 1"/utf8>>,
<<" SYNTAX_EDITIONS -> 2"/utf8>>,
<<" }"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"fn decode_syntax_field() -> decode.Decoder(Syntax) {"/utf8>>,
<<" decode.field(0, fn(field) {"/utf8>>,
<<" use value <- result.try(decode.int32_field(field))"/utf8>>,
<<" case value {"/utf8>>,
<<" 0 -> Ok(SYNTAX_PROTO2)"/utf8>>,
<<" 1 -> Ok(SYNTAX_PROTO3)"/utf8>>,
<<" 2 -> Ok(SYNTAX_EDITIONS)"/utf8>>,
<<" _ -> Error(decode.DecodeError(expected: \"valid syntax value\", found: \"Unknown syntax value: \" <> string.inspect(value), path: []))"/utf8>>,
<<" }"/utf8>>,
<<" })"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 1013).
?DOC(false).
-spec generate_field_definition() -> binary().
generate_field_definition() ->
Lines = [<<"pub type FieldKind {"/utf8>>,
<<" TYPE_UNKNOWN"/utf8>>,
<<" TYPE_DOUBLE"/utf8>>,
<<" TYPE_FLOAT"/utf8>>,
<<" TYPE_INT64"/utf8>>,
<<" TYPE_UINT64"/utf8>>,
<<" TYPE_INT32"/utf8>>,
<<" TYPE_FIXED64"/utf8>>,
<<" TYPE_FIXED32"/utf8>>,
<<" TYPE_BOOL"/utf8>>,
<<" TYPE_STRING"/utf8>>,
<<" TYPE_GROUP"/utf8>>,
<<" TYPE_MESSAGE"/utf8>>,
<<" TYPE_BYTES"/utf8>>,
<<" TYPE_UINT32"/utf8>>,
<<" TYPE_ENUM"/utf8>>,
<<" TYPE_SFIXED32"/utf8>>,
<<" TYPE_SFIXED64"/utf8>>,
<<" TYPE_SINT32"/utf8>>,
<<" TYPE_SINT64"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub type FieldCardinality {"/utf8>>,
<<" CARDINALITY_UNKNOWN"/utf8>>,
<<" CARDINALITY_OPTIONAL"/utf8>>,
<<" CARDINALITY_REQUIRED"/utf8>>,
<<" CARDINALITY_REPEATED"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub type Field {"/utf8>>,
<<" Field("/utf8>>,
<<" kind: FieldKind,"/utf8>>,
<<" cardinality: FieldCardinality,"/utf8>>,
<<" number: Int,"/utf8>>,
<<" name: String,"/utf8>>,
<<" type_url: String,"/utf8>>,
<<" oneof_index: Int,"/utf8>>,
<<" packed: Bool,"/utf8>>,
<<" options: List(Option),"/utf8>>,
<<" json_name: String,"/utf8>>,
<<" default_value: String,"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_field(field: Field) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.enum_field(1, encode_fieldkind_value(field.kind)),"/utf8>>,
<<" encode.enum_field(2, encode_fieldcardinality_value(field.cardinality)),"/utf8>>,
<<" encode.int32_field(3, field.number),"/utf8>>,
<<" encode.string_field(4, field.name),"/utf8>>,
<<" encode.string_field(6, field.type_url),"/utf8>>,
<<" encode.int32_field(7, field.oneof_index),"/utf8>>,
<<" encode.bool_field(8, field.packed),"/utf8>>,
<<" encode.string_field(10, field.json_name),"/utf8>>,
<<" encode.string_field(11, field.default_value),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn field_decoder() -> decode.Decoder(Field) {"/utf8>>,
<<" use kind <- decode.then(decode.enum_field(1, decode_fieldkind_field))"/utf8>>,
<<" use cardinality <- decode.then(decode.enum_field(2, decode_fieldcardinality_field))"/utf8>>,
<<" use number <- decode.then(decode.int32_with_default(3, 0))"/utf8>>,
<<" use name <- decode.then(decode.string_with_default(4, \"\"))"/utf8>>,
<<" use type_url <- decode.then(decode.string_with_default(6, \"\"))"/utf8>>,
<<" use oneof_index <- decode.then(decode.int32_with_default(7, 0))"/utf8>>,
<<" use packed <- decode.then(decode.bool_with_default(8, False))"/utf8>>,
<<" use options <- decode.then(decode.repeated_field(9, fn(_) { Ok([]) }))"/utf8>>,
<<" use json_name <- decode.then(decode.string_with_default(10, \"\"))"/utf8>>,
<<" use default_value <- decode.then(decode.string_with_default(11, \"\"))"/utf8>>,
<<" decode.success(Field("/utf8>>,
<<" kind: kind,"/utf8>>,
<<" cardinality: cardinality,"/utf8>>,
<<" number: number,"/utf8>>,
<<" name: name,"/utf8>>,
<<" type_url: type_url,"/utf8>>,
<<" oneof_index: oneof_index,"/utf8>>,
<<" packed: packed,"/utf8>>,
<<" options: options,"/utf8>>,
<<" json_name: json_name,"/utf8>>,
<<" default_value: default_value,"/utf8>>,
<<" ))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 1101).
?DOC(false).
-spec generate_enum_definition() -> binary().
generate_enum_definition() ->
Lines = [<<"pub type Enum {"/utf8>>,
<<" Enum("/utf8>>,
<<" name: String,"/utf8>>,
<<" enumvalue: List(EnumValue),"/utf8>>,
<<" options: List(Option),"/utf8>>,
<<" source_context: option.Option(SourceContext),"/utf8>>,
<<" syntax: Syntax,"/utf8>>,
<<" edition: String,"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_enum(enum_def: Enum) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.string_field(1, enum_def.name),"/utf8>>,
<<" // Simplified implementation"/utf8>>,
<<" encode.enum_field(5, encode_syntax_value(enum_def.syntax)),"/utf8>>,
<<" encode.string_field(6, enum_def.edition),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn enum_decoder() -> decode.Decoder(Enum) {"/utf8>>,
<<" use name <- decode.then(decode.string_with_default(1, \"\"))"/utf8>>,
<<" use enumvalue <- decode.then(decode.repeated_field(2, fn(_) { Ok([]) }))"/utf8>>,
<<" use options <- decode.then(decode.repeated_field(3, fn(_) { Ok([]) }))"/utf8>>,
<<" use source_context <- decode.then(decode.optional_nested_message(4, sourcecontext_decoder()))"/utf8>>,
<<" use syntax <- decode.then(decode.enum_field(5, decode_syntax_field))"/utf8>>,
<<" use edition <- decode.then(decode.string_with_default(6, \"\"))"/utf8>>,
<<" decode.success(Enum("/utf8>>,
<<" name: name,"/utf8>>,
<<" enumvalue: enumvalue,"/utf8>>,
<<" options: options,"/utf8>>,
<<" source_context: source_context,"/utf8>>,
<<" syntax: syntax,"/utf8>>,
<<" edition: edition,"/utf8>>,
<<" ))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 1143).
?DOC(false).
-spec generate_enumvalue_definition() -> binary().
generate_enumvalue_definition() ->
Lines = [<<"pub type EnumValue {"/utf8>>,
<<" EnumValue("/utf8>>,
<<" name: String,"/utf8>>,
<<" number: Int,"/utf8>>,
<<" options: List(Option),"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_enumvalue(enumvalue: EnumValue) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.string_field(1, enumvalue.name),"/utf8>>,
<<" encode.int32_field(2, enumvalue.number),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn enumvalue_decoder() -> decode.Decoder(EnumValue) {"/utf8>>,
<<" use name <- decode.then(decode.string_with_default(1, \"\"))"/utf8>>,
<<" use number <- decode.then(decode.int32_with_default(2, 0))"/utf8>>,
<<" use options <- decode.then(decode.repeated_field(3, fn(_) { Ok([]) }))"/utf8>>,
<<" decode.success(EnumValue("/utf8>>,
<<" name: name,"/utf8>>,
<<" number: number,"/utf8>>,
<<" options: options,"/utf8>>,
<<" ))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 1174).
?DOC(false).
-spec generate_option_definition() -> binary().
generate_option_definition() ->
Lines = [<<"pub type Option {"/utf8>>,
<<" Option("/utf8>>,
<<" name: String,"/utf8>>,
<<" value: Any,"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_option(option_def: Option) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.string_field(1, option_def.name),"/utf8>>,
<<" encode.field(2, wire.LengthDelimited, encode_any(option_def.value)),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn option_decoder() -> decode.Decoder(Option) {"/utf8>>,
<<" use name <- decode.then(decode.string_with_default(1, \"\"))"/utf8>>,
<<" use value <- decode.then(decode.nested_message(2, any_decoder()))"/utf8>>,
<<" decode.success(Option("/utf8>>,
<<" name: name,"/utf8>>,
<<" value: value,"/utf8>>,
<<" ))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 1202).
?DOC(false).
-spec generate_sourcecontext_definition() -> binary().
generate_sourcecontext_definition() ->
Lines = [<<"pub type SourceContext {"/utf8>>,
<<" SourceContext("/utf8>>,
<<" file_name: String,"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_sourcecontext(sourcecontext: SourceContext) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.string_field(1, sourcecontext.file_name),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn sourcecontext_decoder() -> decode.Decoder(SourceContext) {"/utf8>>,
<<" use file_name <- decode.then(decode.string_with_default(1, \"\"))"/utf8>>,
<<" decode.success(SourceContext("/utf8>>,
<<" file_name: file_name,"/utf8>>,
<<" ))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 1226).
?DOC(false).
-spec generate_api_definition() -> binary().
generate_api_definition() ->
Lines = [<<"pub type Api {"/utf8>>,
<<" Api("/utf8>>,
<<" name: String,"/utf8>>,
<<" methods: List(Method),"/utf8>>,
<<" options: List(Option),"/utf8>>,
<<" version: String,"/utf8>>,
<<" source_context: option.Option(SourceContext),"/utf8>>,
<<" mixins: List(Mixin),"/utf8>>,
<<" syntax: Syntax,"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_api(api: Api) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.string_field(1, api.name),"/utf8>>,
<<" encode.string_field(4, api.version),"/utf8>>,
<<" encode.enum_field(7, encode_syntax_value(api.syntax)),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn api_decoder() -> decode.Decoder(Api) {"/utf8>>,
<<" use name <- decode.then(decode.string_with_default(1, \"\"))"/utf8>>,
<<" use methods <- decode.then(decode.repeated_field(2, fn(_) { Ok([]) }))"/utf8>>,
<<" use options <- decode.then(decode.repeated_field(3, fn(_) { Ok([]) }))"/utf8>>,
<<" use version <- decode.then(decode.string_with_default(4, \"\"))"/utf8>>,
<<" use source_context <- decode.then(decode.optional_nested_message(5, sourcecontext_decoder()))"/utf8>>,
<<" use mixins <- decode.then(decode.repeated_field(6, fn(_) { Ok([]) }))"/utf8>>,
<<" use syntax <- decode.then(decode.enum_field(7, decode_syntax_field))"/utf8>>,
<<" decode.success(Api("/utf8>>,
<<" name: name,"/utf8>>,
<<" methods: methods,"/utf8>>,
<<" options: options,"/utf8>>,
<<" version: version,"/utf8>>,
<<" source_context: source_context,"/utf8>>,
<<" mixins: mixins,"/utf8>>,
<<" syntax: syntax,"/utf8>>,
<<" ))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 1270).
?DOC(false).
-spec generate_method_definition() -> binary().
generate_method_definition() ->
Lines = [<<"pub type Method {"/utf8>>,
<<" Method("/utf8>>,
<<" name: String,"/utf8>>,
<<" request_type_url: String,"/utf8>>,
<<" request_streaming: Bool,"/utf8>>,
<<" response_type_url: String,"/utf8>>,
<<" response_streaming: Bool,"/utf8>>,
<<" options: List(Option),"/utf8>>,
<<" syntax: Syntax,"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_method(method: Method) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.string_field(1, method.name),"/utf8>>,
<<" encode.string_field(2, method.request_type_url),"/utf8>>,
<<" encode.bool_field(3, method.request_streaming),"/utf8>>,
<<" encode.string_field(4, method.response_type_url),"/utf8>>,
<<" encode.bool_field(5, method.response_streaming),"/utf8>>,
<<" encode.enum_field(7, encode_syntax_value(method.syntax)),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn method_decoder() -> decode.Decoder(Method) {"/utf8>>,
<<" use name <- decode.then(decode.string_with_default(1, \"\"))"/utf8>>,
<<" use request_type_url <- decode.then(decode.string_with_default(2, \"\"))"/utf8>>,
<<" use request_streaming <- decode.then(decode.bool_with_default(3, False))"/utf8>>,
<<" use response_type_url <- decode.then(decode.string_with_default(4, \"\"))"/utf8>>,
<<" use response_streaming <- decode.then(decode.bool_with_default(5, False))"/utf8>>,
<<" use options <- decode.then(decode.repeated_field(6, fn(_) { Ok([]) }))"/utf8>>,
<<" use syntax <- decode.then(decode.enum_field(7, decode_syntax_field))"/utf8>>,
<<" decode.success(Method("/utf8>>,
<<" name: name,"/utf8>>,
<<" request_type_url: request_type_url,"/utf8>>,
<<" request_streaming: request_streaming,"/utf8>>,
<<" response_type_url: response_type_url,"/utf8>>,
<<" response_streaming: response_streaming,"/utf8>>,
<<" options: options,"/utf8>>,
<<" syntax: syntax,"/utf8>>,
<<" ))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 1317).
?DOC(false).
-spec generate_mixin_definition() -> binary().
generate_mixin_definition() ->
Lines = [<<"pub type Mixin {"/utf8>>,
<<" Mixin("/utf8>>,
<<" name: String,"/utf8>>,
<<" root: String,"/utf8>>,
<<" )"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn encode_mixin(mixin: Mixin) -> BitArray {"/utf8>>,
<<" encode.message(["/utf8>>,
<<" encode.string_field(1, mixin.name),"/utf8>>,
<<" encode.string_field(2, mixin.root),"/utf8>>,
<<" ])"/utf8>>,
<<"}"/utf8>>,
<<""/utf8>>,
<<"pub fn mixin_decoder() -> decode.Decoder(Mixin) {"/utf8>>,
<<" use name <- decode.then(decode.string_with_default(1, \"\"))"/utf8>>,
<<" use root <- decode.then(decode.string_with_default(2, \"\"))"/utf8>>,
<<" decode.success(Mixin("/utf8>>,
<<" name: name,"/utf8>>,
<<" root: root,"/utf8>>,
<<" ))"/utf8>>,
<<"}"/utf8>>],
gleam@string:join(Lines, <<"\n"/utf8>>).
-file("src/protozoa/internal/codegen.gleam", 585).
?DOC(false).
-spec generate_well_known_type_definition(binary()) -> binary().
generate_well_known_type_definition(Type_name) ->
case Type_name of
<<"google.protobuf.Timestamp"/utf8>> ->
generate_timestamp_definition();
<<"Timestamp"/utf8>> ->
generate_timestamp_definition();
<<"google.protobuf.Duration"/utf8>> ->
generate_duration_definition();
<<"Duration"/utf8>> ->
generate_duration_definition();
<<"google.protobuf.FieldMask"/utf8>> ->
generate_fieldmask_definition();
<<"FieldMask"/utf8>> ->
generate_fieldmask_definition();
<<"google.protobuf.Empty"/utf8>> ->
generate_empty_definition();
<<"Empty"/utf8>> ->
generate_empty_definition();
<<"google.protobuf.Any"/utf8>> ->
generate_any_definition();
<<"Any"/utf8>> ->
generate_any_definition();
<<"google.protobuf.Struct"/utf8>> ->
generate_struct_definition();
<<"Struct"/utf8>> ->
generate_struct_definition();
<<"google.protobuf.StringValue"/utf8>> ->
generate_stringvalue_definition();
<<"StringValue"/utf8>> ->
generate_stringvalue_definition();
<<"google.protobuf.Type"/utf8>> ->
generate_type_definition();
<<"Type"/utf8>> ->
generate_type_definition();
<<"google.protobuf.Field"/utf8>> ->
generate_field_definition();
<<"Field"/utf8>> ->
generate_field_definition();
<<"google.protobuf.Enum"/utf8>> ->
generate_enum_definition();
<<"Enum"/utf8>> ->
generate_enum_definition();
<<"google.protobuf.EnumValue"/utf8>> ->
generate_enumvalue_definition();
<<"EnumValue"/utf8>> ->
generate_enumvalue_definition();
<<"google.protobuf.Option"/utf8>> ->
generate_option_definition();
<<"Option"/utf8>> ->
generate_option_definition();
<<"google.protobuf.SourceContext"/utf8>> ->
generate_sourcecontext_definition();
<<"SourceContext"/utf8>> ->
generate_sourcecontext_definition();
<<"google.protobuf.Api"/utf8>> ->
generate_api_definition();
<<"Api"/utf8>> ->
generate_api_definition();
<<"google.protobuf.Method"/utf8>> ->
generate_method_definition();
<<"Method"/utf8>> ->
generate_method_definition();
<<"google.protobuf.Mixin"/utf8>> ->
generate_mixin_definition();
<<"Mixin"/utf8>> ->
generate_mixin_definition();
_ ->
<<""/utf8>>
end.
-file("src/protozoa/internal/codegen.gleam", 479).
?DOC(false).
-spec generate_well_known_definitions(protozoa@parser:proto_file()) -> binary().
generate_well_known_definitions(Proto_file) ->
Referenced_types = get_referenced_well_known_types(Proto_file),
case Referenced_types of
[] ->
<<""/utf8>>;
_ ->
_pipe = Referenced_types,
_pipe@1 = gleam@list:map(
_pipe,
fun generate_well_known_type_definition/1
),
gleam@string:join(_pipe@1, <<"\n\n"/utf8>>)
end.
-file("src/protozoa/internal/codegen.gleam", 120).
?DOC(false).
-spec generate_file_with_imports(
protozoa@parser:proto_file(),
binary(),
protozoa@internal@type_registry:type_registry()
) -> {ok, binary()} | {error, binary()}.
generate_file_with_imports(Proto_file, File_path, Registry) ->
Header = generate_file_header(File_path),
Imports = generate_imports(Proto_file),
Well_known_defs = generate_well_known_definitions(Proto_file),
Enum_types = protozoa@internal@codegen@types:generate_enum_types(
erlang:element(6, Proto_file)
),
Message_types = protozoa@internal@codegen@types:generate_types_with_registry(
erlang:element(5, Proto_file),
Registry,
File_path
),
Message_encoders = protozoa@internal@codegen@encoders:generate_encoders_with_registry(
erlang:element(5, Proto_file),
Registry,
File_path
),
Message_decoders = protozoa@internal@codegen@decoders:generate_decoders_with_registry(
erlang:element(5, Proto_file),
Registry,
File_path
),
Enum_helpers = protozoa@internal@codegen@encoders:generate_enum_helpers_with_nested(
erlang:element(6, Proto_file),
erlang:element(5, Proto_file)
),
Service_stubs = generate_service_stubs(erlang:element(7, Proto_file)),
Sections = begin
_pipe = [Header,
Imports,
Well_known_defs,
Enum_types,
Message_types,
Message_encoders,
Message_decoders,
Enum_helpers,
Service_stubs],
gleam@list:filter(
_pipe,
fun(Section) -> not gleam@string:is_empty(Section) end
)
end,
{ok, gleam@string:join(Sections, <<"\n\n"/utf8>>)}.
-file("src/protozoa/internal/codegen.gleam", 17).
?DOC(false).
-spec generate_simple_for_testing(protozoa@parser:proto_file()) -> binary().
generate_simple_for_testing(Proto_file) ->
Registry = protozoa@internal@type_registry:new(),
Fake_file_path = <<"test.proto"/utf8>>,
case generate_file_with_imports(Proto_file, Fake_file_path, Registry) of
{ok, Code} ->
Code;
{error, Err} ->
erlang:error(#{gleam_error => panic,
message => (<<"Code generation failed: "/utf8, Err/binary>>),
file => <<?FILEPATH/utf8>>,
module => <<"protozoa/internal/codegen"/utf8>>,
function => <<"generate_simple_for_testing"/utf8>>,
line => 23})
end.
-file("src/protozoa/internal/codegen.gleam", 28).
?DOC(false).
-spec generate_with_imports(
list(protozoa@parser:path()),
protozoa@internal@type_registry:type_registry(),
binary()
) -> {ok, list({binary(), binary()})} | {error, binary()}.
generate_with_imports(Files, Registry, Output_dir) ->
gleam@list:try_map(
Files,
fun(File_entry) ->
Base_name = get_base_name(erlang:element(2, File_entry)),
Output_path = <<<<<<Output_dir/binary, "/"/utf8>>/binary,
Base_name/binary>>/binary,
".gleam"/utf8>>,
gleam@result:'try'(
generate_file_with_imports(
erlang:element(3, File_entry),
erlang:element(2, File_entry),
Registry
),
fun(Code) ->
gleam@result:'try'(
begin
_pipe = simplifile:write(Output_path, Code),
gleam@result:map_error(
_pipe,
fun(_) ->
<<"Failed to write file: "/utf8,
Output_path/binary>>
end
)
end,
fun(_) -> {ok, {Output_path, Code}} end
)
end
)
end
).