-module(protozoa@dev). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/protozoa/dev.gleam"). -export([main/0]). -export_type([command/0, change_result/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( " Protozoa Dev - Protocol Buffer Compiler CLI for Gleam\n" "\n" " CLI tool for generating Gleam code from Protocol Buffer (.proto) files with complete proto3 support.\n" ). -type command() :: generate | check. -type change_result() :: unchanged | {changed, list(binary())}. -file("src/protozoa/dev.gleam", 100). -spec extract_imports(list(binary()), list(binary())) -> {list(binary()), list(binary())}. extract_imports(Args, Acc) -> case Args of [Arg | Rest] -> case gleam_stdlib:string_starts_with(Arg, <<"-I"/utf8>>) of true -> Path = gleam@string:drop_start(Arg, 2), extract_imports(Rest, [Path | Acc]); false -> {lists:reverse(Acc), Args} end; [] -> {lists:reverse(Acc), []} end. -file("src/protozoa/dev.gleam", 89). -spec parse_manual_mode(list(binary())) -> {ok, {command(), binary(), binary(), list(binary())}} | {error, snag:snag()}. parse_manual_mode(Args) -> {Imports, Remaining} = extract_imports(Args, []), case Remaining of [Input, Output] -> {ok, {generate, Input, Output, Imports}}; [Input@1] -> {ok, {generate, Input@1, <<"."/utf8>>, Imports}}; _ -> snag:error(<<"Invalid arguments"/utf8>>) end. -file("src/protozoa/dev.gleam", 118). -spec discover_project_structure() -> {ok, {binary(), binary()}} | {error, snag:snag()}. discover_project_structure() -> gleam@result:'try'( begin _pipe = protozoa@internal@project:name(), gleam@result:map_error( _pipe, fun(_) -> snag:new(<<"Project name not found in gleam.toml"/utf8>>) end ) end, fun(Name) -> Proto_dir = filepath:join( protozoa@internal@project:src(), <> ), gleam@result:'try'( begin _pipe@1 = simplifile_erl:read_directory(Proto_dir), snag:map_error(_pipe@1, fun simplifile:describe_error/1) end, fun(Proto_files) -> Proto_file = <<<<<>/binary, Name/binary>>/binary, ".proto"/utf8>>, case gleam@list:any( Proto_files, fun(F) -> gleam_stdlib:string_ends_with(F, <<".proto"/utf8>>) end ) of true -> {ok, {Proto_file, Proto_dir}}; false -> snag:error(<<"No proto files found"/utf8>>) end end ) end ). -file("src/protozoa/dev.gleam", 62). -spec parse_auto_mode(list(binary())) -> {ok, {command(), binary(), binary(), list(binary())}} | {error, snag:snag()}. parse_auto_mode(Args) -> Cmd = case Args of [<<"check"/utf8>>] -> check; _ -> generate end, case discover_project_structure() of {ok, {Input, Output}} -> {ok, {Cmd, Input, Output, [<<"."/utf8>>]}}; {error, Error} -> case Cmd of check -> {ok, {Cmd, <<"."/utf8>>, <<"."/utf8>>, [<<"."/utf8>>]}}; generate -> _pipe = {error, Error}, snag:context( _pipe, <<"No gleam.toml found or no proto files detected"/utf8>> ) end end. -file("src/protozoa/dev.gleam", 52). -spec parse_args(list(binary())) -> {ok, {command(), binary(), binary(), list(binary())}} | {error, snag:snag()}. parse_args(Args) -> case Args of [] -> parse_auto_mode(Args); [<<"check"/utf8>>] -> parse_auto_mode(Args); [<<"-h"/utf8>>] -> snag:error(<<"help"/utf8>>); [<<"--help"/utf8>>] -> snag:error(<<"help"/utf8>>); _ -> parse_manual_mode(Args) end. -file("src/protozoa/dev.gleam", 226). -spec resolve_all_imports(binary(), list(binary())) -> {ok, {protozoa@parser:proto_file(), protozoa@internal@import_resolver:import_resolver()}} | {error, snag:snag()}. resolve_all_imports(Input, Import_paths) -> Resolver = begin _pipe = protozoa@internal@import_resolver:new(), protozoa@internal@import_resolver:with_search_paths( _pipe, [<<"."/utf8>> | Import_paths] ) end, _pipe@1 = protozoa@internal@import_resolver:resolve_imports(Resolver, Input), gleam@result:map_error( _pipe@1, fun(Err) -> snag:new( <<"Import resolution failed: "/utf8, (protozoa@internal@import_resolver:describe_error(Err))/binary>> ) end ). -file("src/protozoa/dev.gleam", 183). -spec generate_files(binary(), binary(), list(binary())) -> {ok, list(binary())} | {error, snag:snag()}. generate_files(Input, Output, Import_paths) -> _ = simplifile:create_directory_all(Output), gleam@result:'try'( resolve_all_imports(Input, Import_paths), fun(_use0) -> {_, Resolver} = _use0, Files = protozoa@internal@import_resolver:get_all_loaded_files( Resolver ), Registry = protozoa@internal@import_resolver:get_type_registry( Resolver ), Paths = gleam@list:map( Files, fun(Entry) -> {Path, Content} = Entry, {path, Path, Content} end ), gleam@result:'try'( begin _pipe = protozoa@internal@codegen:generate_combined_proto_file( Paths, Registry, Output ), gleam@result:map_error( _pipe, fun(Err) -> snag:new(<<"Codegen failed: "/utf8, Err/binary>>) end ) end, fun(Generated) -> {ok, gleam@list:map( Generated, fun(Entry@1) -> erlang:element(1, Entry@1) end )} end ) end ). -file("src/protozoa/dev.gleam", 208). -spec check_changes(binary(), binary(), list(binary())) -> {ok, change_result()} | {error, snag:snag()}. check_changes(Input, Output, Import_paths) -> case generate_files(Input, Output, Import_paths) of {ok, _} -> {ok, unchanged}; {error, _} -> {ok, unchanged} end. -file("src/protozoa/dev.gleam", 242). -spec print_usage() -> nil. print_usage() -> gleam_stdlib:println( <<"Protozoa Dev - Protocol Buffer Compiler CLI for Gleam"/utf8>> ), gleam_stdlib:println(<<""/utf8>>), gleam_stdlib:println(<<"Recommended Usage:"/utf8>>), gleam_stdlib:println( <<" gleam run -m protozoa_dev # Auto-detect and generate"/utf8>> ), gleam_stdlib:println( <<" gleam run -m protozoa_dev check # Check for changes"/utf8>> ), gleam_stdlib:println(<<""/utf8>>), gleam_stdlib:println(<<"Advanced Usage:"/utf8>>), gleam_stdlib:println( <<" gleam run -m protozoa_dev input.proto [dir] # Manual mode"/utf8>> ), gleam_stdlib:println( <<" gleam run -m protozoa_dev -Ipath input.proto # With import paths"/utf8>> ), gleam_stdlib:println(<<""/utf8>>), gleam_stdlib:println(<<"Options:"/utf8>>), gleam_stdlib:println( <<" -I # Add import search path"/utf8>> ), gleam_stdlib:println( <<" --help # Show help"/utf8>> ). -file("src/protozoa/dev.gleam", 139). -spec run_generate(binary(), binary(), list(binary())) -> nil. run_generate(Input, Output, Import_paths) -> gleam_stdlib:println(<<"🔄 Generating proto files..."/utf8>>), case generate_files(Input, Output, Import_paths) of {ok, Files} -> gleam_stdlib:println( <<<<"✅ Successfully generated "/utf8, (erlang:integer_to_binary(erlang:length(Files)))/binary>>/binary, " file(s):"/utf8>> ), gleam@list:each( Files, fun(F) -> gleam_stdlib:println(<<" - "/utf8, F/binary>>) end ), case shellout:command( <<"gleam"/utf8>>, [<<"format"/utf8>>], <<"."/utf8>>, [] ) of {ok, _} -> nil; {error, {_, String}} -> gleam_stdlib:println_error( <<"❌ Failed to format files: "/utf8, String/binary>> ) end; {error, Err} -> gleam_stdlib:println_error( <<"❌ Generation failed: "/utf8, (snag:pretty_print(Err))/binary>> ), erlang:halt(1) end. -file("src/protozoa/dev.gleam", 166). -spec run_check(binary(), binary(), list(binary())) -> nil. run_check(Input, Output, Import_paths) -> gleam_stdlib:println(<<"🔍 Checking proto file changes..."/utf8>>), case check_changes(Input, Output, Import_paths) of {ok, unchanged} -> gleam_stdlib:println(<<"✅ Files are up to date"/utf8>>); {ok, {changed, Changes}} -> gleam_stdlib:println(<<"⚠️ Changes detected:"/utf8>>), gleam@list:each( Changes, fun(C) -> gleam_stdlib:println(<<" - "/utf8, C/binary>>) end ), gleam_stdlib:println(<<"💡 Run without 'check' to regenerate"/utf8>>), erlang:halt(1); {error, Err} -> gleam_stdlib:println_error( <<"❌ Check failed: "/utf8, (snag:pretty_print(Err))/binary>> ), erlang:halt(1) end. -file("src/protozoa/dev.gleam", 31). ?DOC(" Main CLI entry point\n"). -spec main() -> nil. main() -> Args = erlang:element(4, argv:load()), case parse_args(Args) of {ok, {Cmd, Input, Output, Imports}} -> case Cmd of generate -> run_generate(Input, Output, Imports); check -> run_check(Input, Output, Imports) end; {error, {snag, <<"help"/utf8>>, _}} -> print_usage(), erlang:halt(0); {error, Error} -> gleam_stdlib:println_error( <<"❌ Error: "/utf8, (begin _pipe = Error, snag:pretty_print(_pipe) end)/binary>> ), print_usage(), erlang:halt(1) end.