| // Copyright IBM Corp. 2014, 2026 | |
| // SPDX-License-Identifier: BUSL-1.1 | |
| package stackaddrs | |
| import ( | |
| "github.com/hashicorp/hcl/v2" | |
| "github.com/hashicorp/hcl/v2/hclsyntax" | |
| "github.com/hashicorp/terraform/internal/collections" | |
| "github.com/hashicorp/terraform/internal/tfdiags" | |
| ) | |
| type InputVariable struct { | |
| Name string | |
| } | |
| func (InputVariable) referenceableSigil() {} | |
| func (InputVariable) inStackConfigSigil() {} | |
| func (InputVariable) inStackInstanceSigil() {} | |
| func (v InputVariable) String() string { | |
| return "var." + v.Name | |
| } | |
| func (v InputVariable) UniqueKey() collections.UniqueKey[InputVariable] { | |
| return v | |
| } | |
| // An InputVariable is its own [collections.UniqueKey]. | |
| func (InputVariable) IsUniqueKey(InputVariable) {} | |
| // ConfigInputVariable places an [InputVariable] in the context of a particular [Stack]. | |
| type ConfigInputVariable = InStackConfig[InputVariable] | |
| // AbsInputVariable places an [InputVariable] in the context of a particular [StackInstance]. | |
| type AbsInputVariable = InStackInstance[InputVariable] | |
| func ParseAbsInputVariableStr(s string) (AbsInputVariable, tfdiags.Diagnostics) { | |
| var diags tfdiags.Diagnostics | |
| traversal, hclDiags := hclsyntax.ParseTraversalAbs([]byte(s), "", hcl.InitialPos) | |
| diags = diags.Append(hclDiags) | |
| if diags.HasErrors() { | |
| return AbsInputVariable{}, diags | |
| } | |
| ret, moreDiags := ParseAbsInputVariable(traversal) | |
| return ret, diags.Append(moreDiags) | |
| } | |
| func ParseAbsInputVariable(traversal hcl.Traversal) (AbsInputVariable, tfdiags.Diagnostics) { | |
| if traversal.IsRelative() { | |
| // This is always a caller bug: caller must only pass absolute | |
| // traversals in here. | |
| panic("ParseAbsInputVariable with relative traversal") | |
| } | |
| stackInst, remain, diags := parseInStackInstancePrefix(traversal) | |
| if diags.HasErrors() { | |
| return AbsInputVariable{}, diags | |
| } | |
| if len(remain) != 2 { | |
| // it must be output.name, no more and no less. | |
| return AbsInputVariable{}, diags.Append(&hcl.Diagnostic{ | |
| Severity: hcl.DiagError, | |
| Summary: "Invalid input variable address", | |
| Detail: "The input variable address must be the keyword \"var\" followed by a variable name.", | |
| Subject: traversal.SourceRange().Ptr(), | |
| }) | |
| } | |
| if kwStep, ok := remain[0].(hcl.TraverseAttr); !ok || kwStep.Name != "var" { | |
| return AbsInputVariable{}, diags.Append(&hcl.Diagnostic{ | |
| Severity: hcl.DiagError, | |
| Summary: "Invalid input variable address", | |
| Detail: "The input variable address must be the keyword \"var\" followed by a variable name.", | |
| Subject: remain[0].SourceRange().Ptr(), | |
| }) | |
| } | |
| nameStep, ok := remain[1].(hcl.TraverseAttr) | |
| if !ok { | |
| return AbsInputVariable{}, diags.Append(&hcl.Diagnostic{ | |
| Severity: hcl.DiagError, | |
| Summary: "Invalid input variable address", | |
| Detail: "The input variable address must be the keyword \"var\" followed by a variable name.", | |
| Subject: remain[1].SourceRange().Ptr(), | |
| }) | |
| } | |
| return AbsInputVariable{ | |
| Stack: stackInst, | |
| Item: InputVariable{ | |
| Name: nameStep.Name, | |
| }, | |
| }, diags | |
| } |