blob: 30e3d33ebf35226df468409c320b7661c48112b9 [file] [log] [blame]
// Copyright (c) HashiCorp, Inc.
// 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
}