Packages
caffeine_lang
6.2.2
6.3.1
6.3.0
6.2.2
6.2.1
6.2.0
6.1.2
6.1.1
6.1.0
6.0.0
5.6.0
5.5.0
5.4.4
5.4.3
5.4.2
5.4.1
5.4.0
5.3.0
5.2.0
5.1.1
5.1.0
5.0.12
5.0.11
5.0.10
5.0.8
5.0.7
5.0.6
5.0.5
5.0.4
5.0.1
5.0.0
4.10.0
4.9.0
4.8.3
4.8.2
4.8.1
4.8.0
4.7.9
4.7.8
4.7.7
4.7.6
4.7.5
4.6.7
4.6.6
4.6.5
4.6.4
4.6.3
4.6.2
4.6.0
4.5.1
4.5.0
4.4.4
4.4.3
4.4.1
4.4.0
4.3.7
4.3.6
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.0.2
1.0.1
0.1.0
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.2
0.0.1
A compiler for generating reliability artifacts from service expectation definitions.
Current section
Files
Jump to
Current section
Files
src/caffeine_lang@linker@ir_builder.erl
-module(caffeine_lang@linker@ir_builder).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/caffeine_lang/linker/ir_builder.gleam").
-export([reserved_labels/1, build_all/4]).
-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/linker/ir_builder.gleam", 29).
?DOC(false).
-spec reserved_labels(
gleam@dict:dict(binary(), caffeine_lang@linker@slo_params:param_info())
) -> gleam@set:set(binary()).
reserved_labels(Params) ->
_pipe = Params,
_pipe@1 = maps:keys(_pipe),
gleam@set:from_list(_pipe@1).
-file("src/caffeine_lang/linker/ir_builder.gleam", 333).
?DOC(
" Build the typed indicator dict (`Dict(String, IndicatorSource)`) from the\n"
" raw indicators value-tuple. String-valued indicators become `LiteralQuery`\n"
" (the legacy inline-query form). `ExternalIndicatorValue` entries become\n"
" `ExternalSignal`, with `value_extraction` populated by looking up the\n"
" indicator name in `external_indicator_types` — that's how the AST-level\n"
" type info from the `value:` clause survives the trip through lowering.\n"
" Indicators whose values are neither shape (shouldn't happen post-validate)\n"
" are silently dropped; the validator should have caught them earlier.\n"
).
-spec build_indicator_sources(
gleam@dict:dict(binary(), caffeine_lang@helpers:value_tuple()),
gleam@dict:dict(binary(), caffeine_lang@types:accepted_types())
) -> gleam@dict:dict(binary(), caffeine_lang@linker@ir:indicator_source()).
build_indicator_sources(Index, External_indicator_types) ->
case gleam_stdlib:map_get(Index, <<"indicators"/utf8>>) of
{error, _} ->
maps:new();
{ok, Vt} ->
case erlang:element(4, Vt) of
{dict_value, D} ->
_pipe = D,
_pipe@1 = maps:to_list(_pipe),
_pipe@2 = gleam@list:filter_map(
_pipe@1,
fun(Pair) ->
{Name, Val} = Pair,
case Val of
{string_value, S} ->
{ok, {Name, {literal_query, S}}};
{external_indicator_value,
Source,
Match,
Value_path} ->
Value_extraction = case Value_path of
none ->
none;
{some, Path} ->
case gleam_stdlib:map_get(
External_indicator_types,
Name
) of
{ok, T} ->
{some,
{external_value_extraction,
Path,
T}};
{error, _} ->
none
end
end,
{ok,
{Name,
{external_signal,
Source,
Match,
Value_extraction}}};
_ ->
{error, nil}
end
end
),
maps:from_list(_pipe@2);
_ ->
maps:new()
end
end.
-file("src/caffeine_lang/linker/ir_builder.gleam", 387).
?DOC(
" Extract SLO-specific fields from an indexed Dict of ValueTuples.\n"
" Threshold defaults to the standard default when not present (e.g. unmeasured expectations).\n"
" `description` is sourced from the expectation's leading doc comments, not\n"
" from value tuples. `expectation_type` flows from the bound measurement's\n"
" declared `success_rate` / `time_slice` header (None for unmeasured).\n"
" `external_indicator_types` is the measurement's resolved type constraints\n"
" for external-indicator value extractions, keyed by indicator name; empty\n"
" for unmeasured expectations.\n"
).
-spec build_slo_fields(
gleam@dict:dict(binary(), caffeine_lang@helpers:value_tuple()),
gleam@option:option(binary()),
gleam@option:option(caffeine_lang@frontend@ast:expectation_type()),
gleam@dict:dict(binary(), caffeine_lang@types:accepted_types())
) -> caffeine_lang@linker@ir:slo_fields().
build_slo_fields(Index, Description, Expectation_type, External_indicator_types) ->
Threshold = begin
_pipe = caffeine_lang@helpers:extract_value(
Index,
<<"threshold"/utf8>>,
fun caffeine_lang@value:extract_percentage/1
),
gleam@result:unwrap(_pipe, 99.9)
end,
Indicators = build_indicator_sources(Index, External_indicator_types),
Window_in_days = caffeine_lang@helpers:extract_window_in_days(Index),
Evaluation = begin
_pipe@1 = caffeine_lang@helpers:extract_value(
Index,
<<"evaluation"/utf8>>,
fun caffeine_lang@value:extract_string/1
),
gleam@option:from_result(_pipe@1)
end,
Tags = caffeine_lang@helpers:extract_tags(Index),
Runbook = begin
_pipe@2 = caffeine_lang@helpers:extract_value(
Index,
<<"runbook"/utf8>>,
fun(V) -> case V of
nil_value ->
{ok, none};
{string_value, S} ->
{ok, {some, S}};
_ ->
{error, nil}
end end
),
gleam@result:unwrap(_pipe@2, none)
end,
Relations = caffeine_lang@helpers:extract_depends_on(Index),
Depends_on = case gleam@dict:is_empty(Relations) of
true ->
none;
false ->
{some, Relations}
end,
Below_ms = begin
_pipe@3 = caffeine_lang@helpers:extract_value(
Index,
<<"below_ms"/utf8>>,
fun caffeine_lang@value:extract_float/1
),
gleam@option:from_result(_pipe@3)
end,
{slo_fields,
Threshold,
Indicators,
Window_in_days,
Evaluation,
Tags,
Runbook,
Depends_on,
Description,
Below_ms,
Expectation_type}.
-file("src/caffeine_lang/linker/ir_builder.gleam", 279).
?DOC(
" Resolves a value tuple to a list of strings for use as tags.\n"
" Primitives and refinements produce a single-element list.\n"
" Lists are exploded into multiple string values.\n"
" Dicts and type alias refs are unsupported.\n"
" Optional(None) produces an empty list (filtered out).\n"
" Defaulted(None) produces the default value.\n"
).
-spec resolve_values_for_tag(
caffeine_lang@types:accepted_types(),
caffeine_lang@value:value()
) -> {ok, list(binary())} | {error, nil}.
resolve_values_for_tag(Typ, Val) ->
case Typ of
{primitive_type, _} ->
{ok, [caffeine_lang@value:to_string(Val)]};
{refinement_type, Refinement} ->
case Refinement of
{one_of, Inner, _} ->
resolve_values_for_tag(Inner, Val);
{inclusive_range, Inner@1, _, _} ->
resolve_values_for_tag(Inner@1, Val)
end;
{collection_type, {list, Inner@2}} ->
case Val of
{list_value, Items} ->
_pipe = Items,
_pipe@2 = gleam@list:try_map(
_pipe,
fun(Item) ->
_pipe@1 = resolve_values_for_tag(Inner@2, Item),
gleam@result:map(
_pipe@1,
fun(Strings) -> Strings end
)
end
),
gleam@result:map(_pipe@2, fun lists:append/1);
_ ->
{error, nil}
end;
{collection_type, {dict, _, _}} ->
{error, nil};
{record_type, _} ->
{error, nil};
{modifier_type, {optional, Inner@3}} ->
case Val of
nil_value ->
{ok, []};
_ ->
resolve_values_for_tag(Inner@3, Val)
end;
{modifier_type, {defaulted, Inner@4, Default}} ->
case Val of
nil_value ->
case Inner@4 of
{collection_type, {list, _}} ->
{ok,
caffeine_lang@types:parse_list_default_string(
Default
)};
_ ->
{ok, [Default]}
end;
_ ->
resolve_values_for_tag(Inner@4, Val)
end
end.
-file("src/caffeine_lang/linker/ir_builder.gleam", 254).
?DOC(
" Extract misc metadata from value tuples.\n"
" Filters out reserved labels (derived from artifact params) and unsupported types.\n"
" Each key maps to a list of string values (primitives become single-element\n"
" lists, collection lists are exploded, nulls are excluded).\n"
).
-spec extract_misc_metadata(
list(caffeine_lang@helpers:value_tuple()),
gleam@set:set(binary())
) -> gleam@dict:dict(binary(), list(binary())).
extract_misc_metadata(Value_tuples, Reserved_labels) ->
_pipe = Value_tuples,
_pipe@1 = gleam@list:filter_map(
_pipe,
fun(Value_tuple) ->
gleam@bool:guard(
gleam@set:contains(
Reserved_labels,
erlang:element(2, Value_tuple)
),
{error, nil},
fun() ->
case resolve_values_for_tag(
erlang:element(3, Value_tuple),
erlang:element(4, Value_tuple)
) of
{ok, []} ->
{error, nil};
{ok, Values} ->
{ok, {erlang:element(2, Value_tuple), Values}};
{error, _} ->
{error, nil}
end
end
)
end
),
maps:from_list(_pipe@1).
-file("src/caffeine_lang/linker/ir_builder.gleam", 231).
?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(), caffeine_lang@value:value()),
gleam@dict:dict(binary(), caffeine_lang@types:accepted_types())
) -> list(caffeine_lang@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,
gleam@bool:guard(
gleam@dict:has_key(Merged_inputs, Label),
{error, nil},
fun() ->
case caffeine_lang@types:is_optional_or_defaulted(Typ) of
true ->
{ok, {value_tuple, Label, Typ, nil_value}};
false ->
{error, nil}
end
end
)
end
).
-file("src/caffeine_lang/linker/ir_builder.gleam", 214).
?DOC(" Build value tuples from provided inputs.\n").
-spec build_provided_value_tuples(
gleam@dict:dict(binary(), caffeine_lang@value:value()),
gleam@dict:dict(binary(), caffeine_lang@types:accepted_types())
) -> list(caffeine_lang@helpers:value_tuple()).
build_provided_value_tuples(Merged_inputs, Params) ->
_pipe = Merged_inputs,
_pipe@1 = maps:to_list(_pipe),
gleam@list:filter_map(
_pipe@1,
fun(Pair) ->
{Label, Val} = Pair,
case gleam_stdlib:map_get(Params, Label) of
{ok, Typ} ->
{ok, {value_tuple, Label, Typ, Val}};
{error, nil} ->
{error, nil}
end
end
).
-file("src/caffeine_lang/linker/ir_builder.gleam", 204).
?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(), caffeine_lang@value:value()),
gleam@dict:dict(binary(), caffeine_lang@types:accepted_types())
) -> list(caffeine_lang@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/linker/ir_builder.gleam", 169).
?DOC(
" Build an IR from an unmeasured expectation.\n"
" Uses restricted params (threshold, window_in_days, depends_on) and sets vendor to None.\n"
).
-spec build_unmeasured(
caffeine_lang@linker@expectations:expectation(),
binary(),
binary(),
binary(),
gleam@set:set(binary()),
gleam@dict:dict(binary(), caffeine_lang@types:accepted_types())
) -> caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:linked()).
build_unmeasured(
Expectation,
Org,
Team,
Service,
Reserved_labels,
Unmeasured_params
) ->
Value_tuples = build_value_tuples(
erlang:element(4, Expectation),
Unmeasured_params
),
Index = caffeine_lang@helpers:index_value_tuples(Value_tuples),
Misc_metadata = extract_misc_metadata(Value_tuples, Reserved_labels),
Unique_name = <<<<<<<<Org/binary, "_"/utf8>>/binary, Service/binary>>/binary,
"_"/utf8>>/binary,
(erlang:element(2, Expectation))/binary>>,
Slo = build_slo_fields(
Index,
erlang:element(5, Expectation),
none,
maps:new()
),
{intermediate_representation,
{intermediate_representation_meta_data,
{expectation_label, erlang:element(2, Expectation)},
{org_name, Org},
{service_name, Service},
{measurement_name, <<"unmeasured"/utf8>>},
{team_name, Team},
Misc_metadata},
Unique_name,
Value_tuples,
Slo,
none}.
-file("src/caffeine_lang/linker/ir_builder.gleam", 106).
?DOC(" Build an IR from a measured expectation paired with its measurement.\n").
-spec build_measured(
caffeine_lang@linker@expectations:expectation(),
caffeine_lang@linker@measurements:measurement(caffeine_lang@linker@measurements:measurement_validated()),
binary(),
binary(),
binary(),
gleam@set:set(binary()),
gleam@dict:dict(binary(), caffeine_lang@analysis@vendor:vendor())
) -> {ok,
caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:linked())} |
{error, caffeine_lang@errors:compilation_error()}.
build_measured(
Expectation,
Measurement,
Org,
Team,
Service,
Reserved_labels,
Vendor_lookup
) ->
Merged_inputs = maps:merge(
erlang:element(4, Measurement),
erlang:element(4, Expectation)
),
Value_tuples = build_value_tuples(
Merged_inputs,
erlang:element(3, Measurement)
),
Index = caffeine_lang@helpers:index_value_tuples(Value_tuples),
Misc_metadata = extract_misc_metadata(Value_tuples, Reserved_labels),
Unique_name = <<<<<<<<Org/binary, "_"/utf8>>/binary, Service/binary>>/binary,
"_"/utf8>>/binary,
(erlang:element(2, Expectation))/binary>>,
Slo = build_slo_fields(
Index,
erlang:element(5, Expectation),
erlang:element(6, Measurement),
erlang:element(5, Measurement)
),
Resolved_vendor = case gleam_stdlib:map_get(
Vendor_lookup,
erlang:element(2, Measurement)
) of
{ok, V} ->
{ok, {some, V}};
{error, nil} ->
{error,
caffeine_lang@errors:linker_vendor_resolution_error(
<<<<<<<<<<<<<<<<<<<<"expectation '"/utf8, Org/binary>>/binary,
"."/utf8>>/binary,
Team/binary>>/binary,
"."/utf8>>/binary,
Service/binary>>/binary,
"."/utf8>>/binary,
(erlang:element(2, Expectation))/binary>>/binary,
"' - measurement '"/utf8>>/binary,
(erlang:element(2, Measurement))/binary>>/binary,
"' has no associated vendor"/utf8>>
)}
end,
gleam@result:'try'(
Resolved_vendor,
fun(Resolved_vendor@1) ->
{ok,
{intermediate_representation,
{intermediate_representation_meta_data,
{expectation_label, erlang:element(2, Expectation)},
{org_name, Org},
{service_name, Service},
{measurement_name, erlang:element(2, Measurement)},
{team_name, Team},
Misc_metadata},
Unique_name,
Value_tuples,
Slo,
Resolved_vendor@1}}
end
).
-file("src/caffeine_lang/linker/ir_builder.gleam", 66).
?DOC(" Build intermediate representations from validated expectations for a single file.\n").
-spec build(
list({caffeine_lang@linker@expectations:expectation(),
gleam@option:option(caffeine_lang@linker@measurements:measurement(caffeine_lang@linker@measurements:measurement_validated()))}),
binary(),
gleam@set:set(binary()),
gleam@dict:dict(binary(), caffeine_lang@analysis@vendor:vendor()),
gleam@dict:dict(binary(), caffeine_lang@types:accepted_types())
) -> {ok,
list(caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:linked()))} |
{error, caffeine_lang@errors:compilation_error()}.
build(
Expectations_measurement_collection,
File_path,
Reserved_labels,
Vendor_lookup,
Unmeasured_params
) ->
{Org, Team, Service} = caffeine_lang@helpers:extract_path_prefix(File_path),
_pipe = Expectations_measurement_collection,
gleam@list:try_map(
_pipe,
fun(Expectation_and_measurement_pair) ->
{Expectation, Maybe_measurement} = Expectation_and_measurement_pair,
case Maybe_measurement of
{some, Measurement} ->
build_measured(
Expectation,
Measurement,
Org,
Team,
Service,
Reserved_labels,
Vendor_lookup
);
none ->
{ok,
build_unmeasured(
Expectation,
Org,
Team,
Service,
Reserved_labels,
Unmeasured_params
)}
end
end
).
-file("src/caffeine_lang/linker/ir_builder.gleam", 37).
?DOC(false).
-spec build_all(
list({list({caffeine_lang@linker@expectations:expectation(),
gleam@option:option(caffeine_lang@linker@measurements:measurement(caffeine_lang@linker@measurements:measurement_validated()))}),
binary()}),
gleam@set:set(binary()),
gleam@dict:dict(binary(), caffeine_lang@analysis@vendor:vendor()),
gleam@dict:dict(binary(), caffeine_lang@linker@slo_params:param_info())
) -> {ok,
list(caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:linked()))} |
{error, caffeine_lang@errors:compilation_error()}.
build_all(Expectations_with_paths, Reserved_labels, Vendor_lookup, Params) ->
Unmeasured_params = caffeine_lang@linker@slo_params:unmeasured_param_types(
Params
),
_pipe = Expectations_with_paths,
_pipe@1 = gleam@list:map(
_pipe,
fun(Pair) ->
{Expectations_measurement_collection, File_path} = Pair,
build(
Expectations_measurement_collection,
File_path,
Reserved_labels,
Vendor_lookup,
Unmeasured_params
)
end
),
_pipe@2 = caffeine_lang@errors:from_results(_pipe@1),
gleam@result:map(_pipe@2, fun lists:append/1).