pub struct SemanticModel {Show 27 fields
pub arena: Arena,
pub span_index: SourceSpanIndex,
pub format_version: Option<String>,
pub description: Option<String>,
pub transforms: Vec<String>,
pub raw_top_level_keys: Vec<String>,
pub template_metadata: Option<Value>,
pub rules: Option<Value>,
pub parsed_rules: Vec<TemplateRule>,
pub parameters: HashMap<String, ParameterInfo>,
pub mappings: MappingData,
pub conditions: ConditionModel,
pub resources: HashMap<String, ResolvedResource>,
pub outputs: HashMap<String, ResolvedOutput>,
pub graph: ReferenceGraph,
pub resources_by_type: HashMap<String, Vec<String>>,
pub diagnostics: Vec<ParseDefect>,
pub output_empty_joins: Vec<String>,
pub sam_globals: HashMap<String, HashMap<String, Value>>,
pub sam_implicit_resources: HashSet<String>,
pub globals_param_refs: Vec<String>,
pub is_cdk: bool,
pub fn_if_conditions: Vec<String>,
pub find_in_map_names: HashSet<String>,
pub params_referenced_in_definitions: HashSet<String>,
pub has_dynamic_findinmap_name: bool,
pub resolution_sources: HashMap<(String, String), String>,
/* private fields */
}Fields§
§arena: Arena§span_index: SourceSpanIndex§format_version: Option<String>§description: Option<String>§transforms: Vec<String>§raw_top_level_keys: Vec<String>§template_metadata: Option<Value>§rules: Option<Value>§parsed_rules: Vec<TemplateRule>§parameters: HashMap<String, ParameterInfo>§mappings: MappingData§conditions: ConditionModel§resources: HashMap<String, ResolvedResource>§outputs: HashMap<String, ResolvedOutput>§graph: ReferenceGraph§resources_by_type: HashMap<String, Vec<String>>§diagnostics: Vec<ParseDefect>§output_empty_joins: Vec<String>§sam_globals: HashMap<String, HashMap<String, Value>>§sam_implicit_resources: HashSet<String>§globals_param_refs: Vec<String>§is_cdk: bool§fn_if_conditions: Vec<String>§find_in_map_names: HashSet<String>Mapping names referenced by an Fn::FindInMap with a literal map name,
collected template-wide (resources, outputs, conditions, ForEach bodies).
params_referenced_in_definitions: HashSet<String>Parameter names referenced from within another parameter’s definition
(e.g. a Default of !Ref OtherParam); these still count as usage.
has_dynamic_findinmap_name: boolTrue when any Fn::FindInMap uses a non-literal map name, which disables
the unused-mapping check because usage can no longer be attributed to a
specific mapping.
resolution_sources: HashMap<(String, String), String>Implementations§
Source§impl SemanticModel
impl SemanticModel
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ParseError>
pub fn parse( bytes: &[u8], config: ParseConfig, ) -> Result<ParseResult, ParseError>
pub fn resource(&self, id: &str) -> Option<&ResolvedResource>
The template as the author wrote it, as CloudFormation JSON with every intrinsic function in long form. This is the view an external evaluator that understands CloudFormation syntax - rather than this crate’s resolved model - operates on. Rendered once and cached for the model’s lifetime.
Sourcepub fn lifecycle_attribute_status(
&self,
resource_id: &str,
attribute: &str,
) -> LifecycleAttributeStatus
pub fn lifecycle_attribute_status( &self, resource_id: &str, attribute: &str, ) -> LifecycleAttributeStatus
Reports whether a lifecycle attribute can legally survive condition
evaluation, and whether any reachable authored value has a non-object
shape. Only UpdatePolicy permits Fn::If to remove the whole attribute
with AWS::NoValue; illegal values on the other attributes remain present
for downstream diagnostics.
Sourcepub fn lifecycle_policy_scenarios(
&self,
resource_id: &str,
attribute: &str,
) -> Vec<(Value, HashMap<String, bool>)>
pub fn lifecycle_policy_scenarios( &self, resource_id: &str, attribute: &str, ) -> Vec<(Value, HashMap<String, bool>)>
Expands a lifecycle policy into reachable values while preserving the assumptions for each branch. Whole dynamic leaves are deferred, while a list or object remains invalid regardless of dynamic values nested inside it.
pub fn resources_of_type(&self, type_name: &str) -> &[String]
pub fn resource_condition_is_valid(&self, resource_id: &str) -> bool
Sourcepub fn primary_identifier_conflicts(
&self,
resource_type: &str,
identifier_properties: &[String],
) -> Vec<(Vec<String>, BTreeSet<String>)>
pub fn primary_identifier_conflicts( &self, resource_type: &str, identifier_properties: &[String], ) -> Vec<(Vec<String>, BTreeSet<String>)>
Groups resources that can simultaneously resolve to the same primary-identifier tuple. Each displayed tuple is paired with the ordered set of resources participating in at least one satisfiable collision for the corresponding comparison identity.
pub fn condition_is_valid_for_reachability(&self, condition: &str) -> bool
pub fn resolve(&self, resource_id: &str, path: &str) -> Option<&ResolvedValue>
pub fn resolve_deep( &self, resource_id: &str, path: &str, ) -> Option<ResolvedValue>
Sourcepub fn resolve_unexpanded(
&self,
resource_id: &str,
path: &str,
) -> Option<ResolvedValue>
pub fn resolve_unexpanded( &self, resource_id: &str, path: &str, ) -> Option<ResolvedValue>
Returns the resolved value tree at path without expanding Fn::If or
parameter-enum alternatives. Unlike Self::resolve_deep, this also
traverses a whole-Properties Fn::If; a path absent from one branch is
represented by the dynamic placeholder produced by
resolved_value_at_path. This lookup does not consume scenario budget.
Returns scenarios for each list member at path, expanding every member
independently under conditions that wrap the whole list. Conditions on
sibling members never multiply, and repeated callers share one cached
allocation. This structural query does not consume scenario budget.
Sourcepub fn duplicate_object_field_value_scenario(
&self,
resource_id: &str,
path: &str,
field_name: &str,
) -> Option<HashMap<String, bool>>
pub fn duplicate_object_field_value_scenario( &self, resource_id: &str, path: &str, field_name: &str, ) -> Option<HashMap<String, bool>>
Whether two distinct members of one reachable list alternative have the
same concrete string value for field_name.
Sourcepub fn list_object_missing_required_field_scenarios(
&self,
resource_id: &str,
path: &str,
required_field: &str,
trigger_field: &str,
) -> Vec<(usize, HashMap<String, bool>)>
pub fn list_object_missing_required_field_scenarios( &self, resource_id: &str, path: &str, required_field: &str, trigger_field: &str, ) -> Vec<(usize, HashMap<String, bool>)>
Reachable list members where required_field is absent while
trigger_field is present.
Sourcepub fn list_member_pair_source_paths(
&self,
resource_id: &str,
path: &str,
base_conditions: &HashMap<String, bool>,
) -> BTreeSet<String>
pub fn list_member_pair_source_paths( &self, resource_id: &str, path: &str, base_conditions: &HashMap<String, bool>, ) -> BTreeSet<String>
Returns each source location that can contain two distinct, non-null
list members in a deployment compatible with base_conditions.
Dynamic member values count as present. Members from different outer list
alternatives or different alternatives of one member never form a pair.
Sourcepub fn has_property(&self, resource_id: &str, path: &str) -> bool
pub fn has_property(&self, resource_id: &str, path: &str) -> bool
Whether the resource authors a value at path, whatever that value is.
Presence is a different question from resolvability: a Ref to a
parameter without a default, a Fn::GetAtt, or a Fn::ImportValue has no
literal before deployment yet the property is set. A rule that asks “is
this property provided?” must use this rather than a concrete lookup, or it
reports a missing property on every template that supplies it indirectly.
A Properties block wrapped in Fn::If keeps its values under the branch
paths, so a property present in either branch counts as authored.
Sourcepub fn has_unresolved_scenario(&self, resource_id: &str, path: &str) -> bool
pub fn has_unresolved_scenario(&self, resource_id: &str, path: &str) -> bool
Whether the value at path is unknown before deployment in at least one
scenario, or has no scenario at all. A rule that reasons about every value
a property can take must stop when one of them cannot be known.
Sourcepub fn referenced_resource_or_value_identity(
&self,
resource_id: &str,
path: &str,
) -> Option<String>
pub fn referenced_resource_or_value_identity( &self, resource_id: &str, path: &str, ) -> Option<String>
A key that two values share only when they provably name the same thing.
A Ref or Fn::GetAtt to a resource in this template is keyed by that
resource, so !Ref Vpc and !GetAtt Vpc.VpcId are one key. Every other
value falls back to Self::value_identity. Callers that group by this key
must treat None as “unknown” and neither group nor separate such values.
pub fn is_from_parameter(&self, resource_id: &str, path: &str) -> bool
Sourcepub fn parameter_name_at(&self, resource_id: &str, path: &str) -> Option<&str>
pub fn parameter_name_at(&self, resource_id: &str, path: &str) -> Option<&str>
The parameter whose declaration stood in for the value at path, or None
when the value came from somewhere else. A value that is only known at
deployment is not necessarily a parameter - a cross-stack import and a
dynamic reference are equally unknown - so callers that describe a value to
a reader must ask rather than assume.
Sourcepub fn value_identity(&self, resource_id: &str, path: &str) -> Option<String>
pub fn value_identity(&self, resource_id: &str, path: &str) -> Option<String>
A key that two values share only when they are provably the same value, or
None when nothing about the value settles the question.
A value that resolves before deployment is keyed by its contents, so the
authored form does not matter. A value that stays opaque is keyed by the
expression that produces it, because that is the only thing that can show
two such values are one value. Callers that compare keys must treat None
and two differing keys alike: neither proves the values differ, so neither
permits a claim that they are the same.
Sourcepub fn is_from_intrinsic(&self, resource_id: &str, path: &str) -> bool
pub fn is_from_intrinsic(&self, resource_id: &str, path: &str) -> bool
True when the value at path (or any ancestor up to the resource root) was
produced by an intrinsic function. Used by rules that skip hardcoded-literal
checks when the property value comes from Fn::GetAZs, Ref, etc.
pub fn substituted_paths_under( &self, resource_id: &str, base_path: &str, ) -> HashSet<String>
Sourcepub fn scenario_budget_exhausted(&self) -> bool
pub fn scenario_budget_exhausted(&self) -> bool
Whether this model has spent its cumulative scenario-expansion budget.
Mirrors ConditionModel::satisfiability_budget_exhausted for the
scenario path: callers that drive many resolve_scenarios queries stop
producing new scenarios once further expansion would only be truncated.
Sourcepub fn record_budget_exhaustion(&self, kind: BudgetKind)
pub fn record_budget_exhaustion(&self, kind: BudgetKind)
Record that a budget kind was exhausted. Delegates to the shared tracker.
Sourcepub fn exhausted_budget_kinds(&self) -> BTreeSet<BudgetKind>
pub fn exhausted_budget_kinds(&self) -> BTreeSet<BudgetKind>
Returns the set of exhausted budget kinds in deterministic order.
Sourcepub fn budget_analysis_incomplete(&self) -> bool
pub fn budget_analysis_incomplete(&self) -> bool
Whether any exhausted budget makes the analysis incomplete.
Sourcepub fn scenario_combinations_used(&self) -> u64
pub fn scenario_combinations_used(&self) -> u64
Cumulative scenarios materialized by this model so far.
Sourcepub fn scenario_expansion_curtailed(&self) -> bool
pub fn scenario_expansion_curtailed(&self) -> bool
Whether any scenario expansion for this model omitted possible results because a per-value or model-wide analysis limit was reached. The flag is monotonic so callers can distinguish complete expansion from conservative fallback behavior.
Returns one immutable whole-properties scenario allocation shared across read-only callers, materializing and caching it on first access. The lock is held across expansion so a resource’s scenarios are computed once and its budget charged once.
Sourcepub fn resolve_properties_scenarios(
&self,
resource_id: &str,
) -> Vec<(ResolvedValue, HashMap<String, bool>)>
pub fn resolve_properties_scenarios( &self, resource_id: &str, ) -> Vec<(ResolvedValue, HashMap<String, bool>)>
Owned copy of Self::resolve_properties_scenarios_shared; read-only
callers should use the shared accessor to avoid cloning the cached
expansion.
Sourcepub fn resolve_properties_scenarios_projected(
&self,
resource_id: &str,
property_names: &[&str],
) -> Arc<Vec<(ResolvedValue, HashMap<String, bool>)>> ⓘ
pub fn resolve_properties_scenarios_projected( &self, resource_id: &str, property_names: &[&str], ) -> Arc<Vec<(ResolvedValue, HashMap<String, bool>)>> ⓘ
Like Self::resolve_properties_scenarios_shared but expands only the
named top-level properties. Conditions that gate other properties never
enter the expansion, so the scenario count grows with the conditions on
the requested properties alone, and a scenario’s assumptions carry only
the conditions its values depend on.
Sourcepub fn property_absence_scenarios(
&self,
resource_id: &str,
property_name: &str,
) -> Vec<HashMap<String, bool>>
pub fn property_absence_scenarios( &self, resource_id: &str, property_name: &str, ) -> Vec<HashMap<String, bool>>
The condition assignments under which the top-level property
property_name is absent at deployment: undeclared, or resolving to
AWS::NoValue. A macro-owned branch is unknown rather than absent, and
an explicitly authored dynamic value remains present. Only the conditions
that decide the property’s own presence appear, never conditions nested
inside a present value, so the result stays linear in the property’s
Fn::If depth. Empty when the property is always present or the resource’s
properties are otherwise dynamic. Scenarios incompatible with the resource’s
own condition or the template condition model are excluded.
Whether the authored node at path is exactly a Ref to target.
Sourcepub fn parameter_has_override(&self, parameter_name: &str) -> bool
pub fn parameter_has_override(&self, parameter_name: &str) -> bool
Whether the caller supplied a concrete override for this parameter.
Sourcepub fn scenario_source_path(
&self,
resource_id: &str,
effective_path: &str,
conditions: &HashMap<String, bool>,
) -> Option<String>
pub fn scenario_source_path( &self, resource_id: &str, effective_path: &str, conditions: &HashMap<String, bool>, ) -> Option<String>
Returns the authored, branch-qualified source path for an effective path in
one resolved scenario. The returned path uses the same dotted form as
resolver source paths and can be passed to Self::resource_span.
Sourcepub fn scenario_uses_pseudo_parameter(
&self,
resource_id: &str,
effective_path: &str,
conditions: &HashMap<String, bool>,
) -> bool
pub fn scenario_uses_pseudo_parameter( &self, resource_id: &str, effective_path: &str, conditions: &HashMap<String, bool>, ) -> bool
Whether the selected value is authored from an AWS pseudo parameter.
Sourcepub fn scenario_uses_unresolved_parameter(
&self,
resource_id: &str,
effective_path: &str,
conditions: &HashMap<String, bool>,
) -> bool
pub fn scenario_uses_unresolved_parameter( &self, resource_id: &str, effective_path: &str, conditions: &HashMap<String, bool>, ) -> bool
Whether a scenario depends on a parameter whose final deployment value is unknown. Ordinary caller overrides are fixed values; overrides for SSM value parameter types remain lookup names that CloudFormation resolves.
Returns one immutable allocation of the scenarios for the value at path
under the default per-value limit, shared across read-only callers.
Sourcepub fn resolve_scenarios(
&self,
resource_id: &str,
path: &str,
) -> Vec<(ResolvedValue, HashMap<String, bool>)>
pub fn resolve_scenarios( &self, resource_id: &str, path: &str, ) -> Vec<(ResolvedValue, HashMap<String, bool>)>
Owned copy of Self::resolve_scenarios_shared; read-only callers should
use the shared accessor to avoid cloning the memoized expansion.
Expands the value at path under a per-value scenario limit, reporting
whether the expansion was curtailed. Results are memoized per
(resource, path, limit) so repeated queries, including the default-limit
Self::resolve_scenarios_shared, share one allocation and charge the
cumulative budget once.
Sourcepub fn resolve_scenarios_with_limit(
&self,
resource_id: &str,
path: &str,
per_value_limit: usize,
) -> (Vec<(ResolvedValue, HashMap<String, bool>)>, bool)
pub fn resolve_scenarios_with_limit( &self, resource_id: &str, path: &str, per_value_limit: usize, ) -> (Vec<(ResolvedValue, HashMap<String, bool>)>, bool)
Owned copy of Self::resolve_scenarios_with_limit_shared; read-only
callers should use the shared accessor to avoid cloning the memoized
expansion.
Returns one immutable scenario allocation shared across read-only callers.
pub fn resolve_scenarios_json( &self, resource_id: &str, path: &str, ) -> Vec<(Value, HashMap<String, bool>)>
pub fn follow_ref(&self, resource_id: &str, path: &str) -> Option<&str>
pub fn source_location(&self, path: &str) -> Option<&SourceSpan>
Sourcepub fn resource_span(&self, resource_id: &str, prop_path: &str) -> SourceSpan
pub fn resource_span(&self, resource_id: &str, prop_path: &str) -> SourceSpan
Returns the source span for a resource property path, falling back to the resource-level span if the specific path is not found.
The span index is keyed with slash-separated paths, so a dotted,
resource-relative path (Properties.BucketName) is normalized to slash
form before lookup - the same normalization Self::diagnostic_span
applies. Callers pass paths in either form, so accepting only slash form
here would silently mislocate every dotted-path diagnostic onto the
resource declaration line.
Sourcepub fn diagnostic_span(
&self,
resource_id: Option<&str>,
property_path: &str,
) -> Option<SourceSpan>
pub fn diagnostic_span( &self, resource_id: Option<&str>, property_path: &str, ) -> Option<SourceSpan>
Best-effort span for a diagnostic identified by its optional resource and property path, walking up to the nearest indexed ancestor.
The path form disambiguates how to root it, which matters because a segment
like Metadata names both a top-level section and a resource property:
- A slash form (
Outputs/X/Value,Conditions/C/Fn::And) is already an absolute, section-rooted span-index key and is resolved as written. - A bare path with no resource (
BogusSection) is a top-level key and is also resolved directly. - A dotted or bare form with a resource (
Properties.Foo,Metadata) is relative to that resource, so it is rooted atResources/<rid>before lookup - never matched against a same-named top-level section.
Returns None when nothing along the chosen candidate is indexed, so callers
can fall back to a section span.
Sourcepub fn estimated_string_length_bounds(
&self,
resource_id: &str,
path: &str,
) -> Option<(usize, usize)>
pub fn estimated_string_length_bounds( &self, resource_id: &str, path: &str, ) -> Option<(usize, usize)>
Bounds on the length of a string value the template does not state
literally - one built by an intrinsic, or chosen from a parameter’s
AllowedValues. None when the length cannot be pinned for every
possibility, and also when the template does state the value literally,
because schema validation checks a literal against the constraint directly.
Both engines decide what to report from this one answer, so neither can reach a different conclusion about the same property.