-module(caffeine_lang@codegen@datadog_template). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/caffeine_lang/codegen/datadog_template.gleam"). -export([cleanup_empty_template_artifacts/1, resolve_template/2, parse_template_type/1, parse_template_variable/1, parse_and_resolve_query_template/3]). -export_type([template_variable/0, datadog_template_type/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. -type template_variable() :: {template_variable, binary(), binary(), datadog_template_type()}. -type datadog_template_type() :: raw | default | 'not'. -file("src/caffeine_lang/codegen/datadog_template.gleam", 160). -spec do_cleanup(binary()) -> binary(). do_cleanup(Query) -> _pipe = Query, _pipe@1 = gleam@string:replace(_pipe, <<", ,"/utf8>>, <<","/utf8>>), _pipe@2 = gleam@string:replace(_pipe@1, <<",,"/utf8>>, <<","/utf8>>), _pipe@3 = gleam@string:replace( _pipe@2, <<" AND AND "/utf8>>, <<" AND "/utf8>> ), _pipe@4 = gleam@string:replace(_pipe@3, <<", }"/utf8>>, <<"}"/utf8>>), _pipe@5 = gleam@string:replace(_pipe@4, <<",}"/utf8>>, <<"}"/utf8>>), _pipe@6 = gleam@string:replace(_pipe@5, <<"{, "/utf8>>, <<"{"/utf8>>), _pipe@7 = gleam@string:replace(_pipe@6, <<"{,"/utf8>>, <<"{"/utf8>>), _pipe@8 = gleam@string:replace(_pipe@7, <<", )"/utf8>>, <<")"/utf8>>), _pipe@9 = gleam@string:replace(_pipe@8, <<",)"/utf8>>, <<")"/utf8>>), _pipe@10 = gleam@string:replace(_pipe@9, <<"(, "/utf8>>, <<"("/utf8>>), _pipe@11 = gleam@string:replace(_pipe@10, <<"(,"/utf8>>, <<"("/utf8>>), _pipe@12 = gleam@string:replace(_pipe@11, <<" AND }"/utf8>>, <<"}"/utf8>>), _pipe@13 = gleam@string:replace(_pipe@12, <<"{ AND "/utf8>>, <<"{"/utf8>>), _pipe@14 = gleam@string:replace(_pipe@13, <<"{ }"/utf8>>, <<"{}"/utf8>>), gleam@string:replace(_pipe@14, <<"( )"/utf8>>, <<"()"/utf8>>). -file("src/caffeine_lang/codegen/datadog_template.gleam", 152). ?DOC(false). -spec cleanup_empty_template_artifacts(binary()) -> binary(). cleanup_empty_template_artifacts(Query) -> Cleaned = do_cleanup(Query), case Cleaned =:= Query of true -> Cleaned; false -> cleanup_empty_template_artifacts(Cleaned) end. -file("src/caffeine_lang/codegen/datadog_template.gleam", 304). ?DOC( " Formats a list of string values according to the template variable.\n" " ASSUMPTION: we already checked the value type is correct and the label matches\n" " the Datadog template name. Thus instead of passing in a ValueTuple\n" " we can just pass in the raw list value of strings.\n" ). -spec resolve_list_value(template_variable(), list(binary())) -> binary(). resolve_list_value(Template, Values) -> case {erlang:element(4, Template), Values} of {_, []} -> <<""/utf8>>; {raw, Values@1} -> _pipe = Values@1, gleam@string:join(_pipe, <<", "/utf8>>); {default, Values@2} -> datadog_query@filter:tag_in(erlang:element(3, Template), Values@2); {'not', Values@3} -> datadog_query@filter:tag_not_in( erlang:element(3, Template), Values@3 ) end. -file("src/caffeine_lang/codegen/datadog_template.gleam", 292). ?DOC( " Formats a string value according to the template variable.\n" " Returns the formatted string ready for insertion into a Datadog query.\n" " Wildcards in the value are preserved as-is.\n" " ASSUMPTION: we already checked the value type is correct and the label matches\n" " the Datadog template name. Thus instead of passing in a ValueTuple\n" " we can just pass in the raw string value.\n" ). -spec resolve_string_value(template_variable(), binary()) -> binary(). resolve_string_value(Template, Value) -> case erlang:element(4, Template) of raw -> Value; default -> datadog_query@filter:tag(erlang:element(3, Template), Value); 'not' -> datadog_query@filter:negated_tag(erlang:element(3, Template), Value) end. -file("src/caffeine_lang/codegen/datadog_template.gleam", 256). ?DOC(false). -spec resolve_template(template_variable(), caffeine_lang@helpers:value_tuple()) -> {ok, binary()} | {error, caffeine_lang@errors:compilation_error()}. resolve_template(Template, Value_tuple) -> gleam@result:'try'( case erlang:element(2, Template) =:= erlang:element(2, Value_tuple) of true -> {ok, nil}; _ -> {error, caffeine_lang@errors:semantic_analysis_template_resolution_error( <<<<<<<<"Mismatch between template input name ("/utf8, (erlang:element(2, Template))/binary>>/binary, ") and input value label ("/utf8>>/binary, (erlang:element(2, Value_tuple))/binary>>/binary, ")."/utf8>> )} end, fun(_) -> case caffeine_lang@types:resolve_to_string( erlang:element(3, Value_tuple), erlang:element(4, Value_tuple), fun(_capture) -> resolve_string_value(Template, _capture) end, fun(_capture@1) -> resolve_list_value(Template, _capture@1) end ) of {ok, Resolved} -> {ok, Resolved}; {error, Msg} -> {error, caffeine_lang@errors:semantic_analysis_template_resolution_error( Msg )} end end ). -file("src/caffeine_lang/codegen/datadog_template.gleam", 241). ?DOC(false). -spec parse_template_type(binary()) -> {ok, datadog_template_type()} | {error, caffeine_lang@errors:compilation_error()}. parse_template_type(Type_string) -> case Type_string of <<"not"/utf8>> -> {ok, 'not'}; _ -> {error, caffeine_lang@errors:semantic_analysis_template_parse_error( <<"Unknown template type: "/utf8, Type_string/binary>> )} end. -file("src/caffeine_lang/codegen/datadog_template.gleam", 317). ?DOC(" Helper to parse Datadog format template variables (with ->).\n"). -spec parse_datadog_template_variable(binary(), binary()) -> {ok, template_variable()} | {error, caffeine_lang@errors:compilation_error()}. parse_datadog_template_variable(Input_name, Rest) -> case gleam@string:split_once(Rest, <<":"/utf8>>) of {error, _} -> {ok, {template_variable, gleam@string:trim(Rest), Input_name, default}}; {ok, {Datadog_attr, Type_string}} -> case parse_template_type(gleam@string:trim(Type_string)) of {error, E} -> {error, E}; {ok, Template_type} -> {ok, {template_variable, gleam@string:trim(Datadog_attr), Input_name, Template_type}} end end. -file("src/caffeine_lang/codegen/datadog_template.gleam", 197). ?DOC(false). -spec parse_template_variable(binary()) -> {ok, template_variable()} | {error, caffeine_lang@errors:compilation_error()}. parse_template_variable(Variable) -> case gleam@string:split_once(Variable, <<"->"/utf8>>) of {error, _} -> Trimmed = gleam@string:trim(Variable), case Trimmed of <<""/utf8>> -> {error, caffeine_lang@errors:semantic_analysis_template_parse_error( <<"Empty template variable name: "/utf8, Variable/binary>> )}; _ -> {ok, {template_variable, Trimmed, <<""/utf8>>, raw}} end; {ok, {Input_name, Rest}} -> Trimmed_input = gleam@string:trim(Input_name), case {Trimmed_input, Rest} of {<<""/utf8>>, _} -> {error, caffeine_lang@errors:semantic_analysis_template_parse_error( <<"Empty input name in template: "/utf8, Variable/binary>> )}; {_, <<""/utf8>>} -> {error, caffeine_lang@errors:semantic_analysis_template_parse_error( <<"Empty label name in template: "/utf8, Variable/binary>> )}; {_, _} -> parse_datadog_template_variable(Trimmed_input, Rest) end end. -file("src/caffeine_lang/codegen/datadog_template.gleam", 96). ?DOC( " Internal recursive implementation of template resolution.\n" " Returns a StringTree so per-placeholder appends are O(1) on the BEAM;\n" " the caller realizes it to a String once at the top.\n" ). -spec do_parse_and_resolve_query_template( binary(), gleam@dict:dict(binary(), caffeine_lang@helpers:value_tuple()) ) -> {ok, gleam@string_tree:string_tree()} | {error, caffeine_lang@errors:compilation_error()}. do_parse_and_resolve_query_template(Query, Index) -> case gleam@string:split_once(Query, <<"$$"/utf8>>) of {error, _} -> {ok, gleam_stdlib:identity(Query)}; {ok, {Before, Rest}} -> case gleam@string:split_once(Rest, <<"$$"/utf8>>) of {error, _} -> {error, caffeine_lang@errors:semantic_analysis_template_parse_error( <<"Unexpected incomplete `$$` for substring: "/utf8, Query/binary>> )}; {ok, {Inside, Rest@1}} -> gleam@result:'try'( do_parse_and_resolve_query_template(Rest@1, Index), fun(Rest_of_items) -> gleam@result:'try'( parse_template_variable(Inside), fun(Template) -> gleam@result:'try'( begin _pipe = Index, _pipe@1 = gleam_stdlib:map_get( _pipe, erlang:element(2, Template) ), gleam@result:replace_error( _pipe@1, caffeine_lang@errors:semantic_analysis_template_parse_error( <<"Missing input for template: "/utf8, (erlang:element( 2, Template ))/binary>> ) ) end, fun(Value_tuple) -> gleam@result:'try'( resolve_template( Template, Value_tuple ), fun(Resolved_template) -> {ok, begin _pipe@2 = gleam_stdlib:identity( Before ), _pipe@3 = gleam@string_tree:append( _pipe@2, Resolved_template ), gleam_stdlib:iodata_append( _pipe@3, Rest_of_items ) end} end ) end ) end ) end ) end end. -file("src/caffeine_lang/codegen/datadog_template.gleam", 80). ?DOC(false). -spec parse_and_resolve_query_template( binary(), list(caffeine_lang@helpers:value_tuple()), binary() ) -> {ok, binary()} | {error, caffeine_lang@errors:compilation_error()}. parse_and_resolve_query_template(Query, Value_tuples, Identifier) -> Index = caffeine_lang@helpers:index_value_tuples(Value_tuples), gleam@result:'try'( begin _pipe = do_parse_and_resolve_query_template(Query, Index), gleam@result:map_error( _pipe, fun(Err) -> caffeine_lang@errors:prefix_error(Err, Identifier) end ) end, fun(Resolved) -> {ok, cleanup_empty_template_artifacts( unicode:characters_to_binary(Resolved) )} end ).