-module(caffeine_lang@parser@ir_builder). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/caffeine_lang/parser/ir_builder.gleam"). -export([extract_path_prefix/1, build_all/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -file("src/caffeine_lang/parser/ir_builder.gleam", 32). ?DOC(false). -spec extract_path_prefix(binary()) -> {binary(), binary(), binary()}. extract_path_prefix(Path) -> case begin _pipe = Path, _pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>), _pipe@2 = lists:reverse(_pipe@1), _pipe@3 = gleam@list:take(_pipe@2, 3), _pipe@4 = lists:reverse(_pipe@3), gleam@list:map( _pipe@4, fun(Segment) -> case gleam_stdlib:string_ends_with( Segment, <<".caffeine"/utf8>> ) of true -> gleam@string:drop_end(Segment, 9); false -> case gleam_stdlib:string_ends_with( Segment, <<".json"/utf8>> ) of true -> gleam@string:drop_end(Segment, 5); false -> Segment end end end ) end of [Org, Team, Service] -> {Org, Team, Service}; _ -> {<<"unknown"/utf8>>, <<"unknown"/utf8>>, <<"unknown"/utf8>>} end. -file("src/caffeine_lang/parser/ir_builder.gleam", 106). ?DOC(" Build value tuples from provided inputs.\n"). -spec build_provided_value_tuples( gleam@dict:dict(binary(), gleam@dynamic:dynamic_()), gleam@dict:dict(binary(), caffeine_lang@common@accepted_types:accepted_types()) ) -> list(caffeine_lang@common@helpers:value_tuple()). build_provided_value_tuples(Merged_inputs, Params) -> _pipe = Merged_inputs, _pipe@1 = maps:keys(_pipe), gleam@list:map( _pipe@1, fun(Label) -> Value@1 = case begin _pipe@2 = Merged_inputs, gleam_stdlib:map_get(_pipe@2, Label) end of {ok, Value} -> Value; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"caffeine_lang/parser/ir_builder"/utf8>>, function => <<"build_provided_value_tuples"/utf8>>, line => 114, value => _assert_fail, start => 3964, 'end' => 4019, pattern_start => 3975, pattern_end => 3984}) end, Typ@1 = case begin _pipe@3 = Params, gleam_stdlib:map_get(_pipe@3, Label) end of {ok, Typ} -> Typ; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"caffeine_lang/parser/ir_builder"/utf8>>, function => <<"build_provided_value_tuples"/utf8>>, line => 115, value => _assert_fail@1, start => 4024, 'end' => 4070, pattern_start => 4035, pattern_end => 4042}) end, {value_tuple, Label, Typ@1, Value@1} end ). -file("src/caffeine_lang/parser/ir_builder.gleam", 147). ?DOC( " Checks if a type is optional or has a default value.\n" " This includes:\n" " - ModifierType(Optional(_))\n" " - ModifierType(Defaulted(_, _))\n" " - RefinementType(OneOf(ModifierType(Optional(_)), _))\n" " - RefinementType(OneOf(ModifierType(Defaulted(_, _)), _))\n" ). -spec is_optional_or_defaulted( caffeine_lang@common@accepted_types:accepted_types() ) -> boolean(). is_optional_or_defaulted(Typ) -> case Typ of {modifier_type, {optional, _}} -> true; {modifier_type, {defaulted, _, _}} -> true; {refinement_type, {one_of, Inner, _}} -> is_optional_or_defaulted(Inner); _ -> false end. -file("src/caffeine_lang/parser/ir_builder.gleam", 122). ?DOC( " Build value tuples for Optional/Defaulted params that weren't provided.\n" " These need to be in value_tuples so the templatizer can resolve them.\n" ). -spec build_unprovided_optional_value_tuples( gleam@dict:dict(binary(), gleam@dynamic:dynamic_()), gleam@dict:dict(binary(), caffeine_lang@common@accepted_types:accepted_types()) ) -> list(caffeine_lang@common@helpers:value_tuple()). build_unprovided_optional_value_tuples(Merged_inputs, Params) -> _pipe = Params, _pipe@1 = maps:to_list(_pipe), gleam@list:filter_map( _pipe@1, fun(Param) -> {Label, Typ} = Param, case gleam@dict:has_key(Merged_inputs, Label) of true -> {error, nil}; false -> case is_optional_or_defaulted(Typ) of true -> {ok, {value_tuple, Label, Typ, gleam@dynamic:nil()}}; false -> {error, nil} end end end ). -file("src/caffeine_lang/parser/ir_builder.gleam", 96). ?DOC( " Build value tuples from merged inputs and params.\n" " Includes both provided inputs and unprovided Optional/Defaulted params.\n" ). -spec build_value_tuples( gleam@dict:dict(binary(), gleam@dynamic:dynamic_()), gleam@dict:dict(binary(), caffeine_lang@common@accepted_types:accepted_types()) ) -> list(caffeine_lang@common@helpers:value_tuple()). build_value_tuples(Merged_inputs, Params) -> Provided = build_provided_value_tuples(Merged_inputs, Params), Unprovided = build_unprovided_optional_value_tuples(Merged_inputs, Params), lists:append(Provided, Unprovided). -file("src/caffeine_lang/parser/ir_builder.gleam", 199). ?DOC(" Convert Result(a, String) to Result(a, Nil)\n"). -spec result_to_nil_error({ok, JAZ} | {error, binary()}) -> {ok, JAZ} | {error, nil}. result_to_nil_error(Result) -> case Result of {ok, Val} -> {ok, Val}; {error, _} -> {error, nil} end. -file("src/caffeine_lang/parser/ir_builder.gleam", 183). ?DOC( " Resolves a value tuple to a string for use as a tag.\n" " Handles Defaulted types by applying their default values when not provided.\n" ). -spec resolve_value_for_tag(caffeine_lang@common@helpers:value_tuple()) -> {ok, binary()} | {error, nil}. resolve_value_for_tag(Value_tuple) -> Identity = fun(S) -> S end, List_join = fun(Items) -> gleam@string:join(Items, <<","/utf8>>) end, _pipe = caffeine_lang@common@accepted_types:resolve_to_string( erlang:element(3, Value_tuple), erlang:element(4, Value_tuple), Identity, List_join ), result_to_nil_error(_pipe). -file("src/caffeine_lang/parser/ir_builder.gleam", 160). ?DOC( " Extract misc metadata from value tuples.\n" " Filters out non-string values and specific reserved labels.\n" " Uses type-aware resolution to apply defaults from Defaulted types.\n" ). -spec extract_misc_metadata(list(caffeine_lang@common@helpers:value_tuple())) -> gleam@dict:dict(binary(), binary()). extract_misc_metadata(Value_tuples) -> _pipe = Value_tuples, _pipe@1 = gleam@list:filter_map( _pipe, fun(Value_tuple) -> case erlang:element(2, Value_tuple) of <<"window_in_days"/utf8>> -> {error, nil}; <<"threshold"/utf8>> -> {error, nil}; <<"value"/utf8>> -> {error, nil}; _ -> case resolve_value_for_tag(Value_tuple) of {ok, Value_string} -> {ok, {erlang:element(2, Value_tuple), Value_string}}; {error, _} -> {error, nil} end end end ), maps:from_list(_pipe@1). -file("src/caffeine_lang/parser/ir_builder.gleam", 59). ?DOC(" Build intermediate representations from validated expectations for a single file.\n"). -spec build( list({caffeine_lang@parser@expectations:expectation(), caffeine_lang@parser@blueprints:blueprint()}), binary() ) -> list(caffeine_lang@middle_end@semantic_analyzer:intermediate_representation()). build(Expectations_blueprint_collection, File_path) -> {Org, Team, Service} = extract_path_prefix(File_path), _pipe = Expectations_blueprint_collection, gleam@list:map( _pipe, fun(Expectation_and_blueprint_pair) -> {Expectation, Blueprint} = Expectation_and_blueprint_pair, Merged_inputs = maps:merge( erlang:element(5, Blueprint), erlang:element(4, Expectation) ), Value_tuples = build_value_tuples( Merged_inputs, erlang:element(4, Blueprint) ), Misc_metadata = extract_misc_metadata(Value_tuples), Unique_name = <<<<<<<>/binary, Service/binary>>/binary, "_"/utf8>>/binary, (erlang:element(2, Expectation))/binary>>, {intermediate_representation, {intermediate_representation_meta_data, erlang:element(2, Expectation), Org, Service, erlang:element(2, Blueprint), Team, Misc_metadata}, Unique_name, erlang:element(3, Blueprint), Value_tuples, none} end ). -file("src/caffeine_lang/parser/ir_builder.gleam", 18). ?DOC(false). -spec build_all( list({list({caffeine_lang@parser@expectations:expectation(), caffeine_lang@parser@blueprints:blueprint()}), binary()}) ) -> list(caffeine_lang@middle_end@semantic_analyzer:intermediate_representation()). build_all(Expectations_with_paths) -> _pipe = Expectations_with_paths, _pipe@1 = gleam@list:map( _pipe, fun(Pair) -> {Expectations_blueprint_collection, File_path} = Pair, build(Expectations_blueprint_collection, File_path) end ), lists:append(_pipe@1).