blob: 0c955d95e223c8781a5ec8f7a30788b3cfd9bce2 [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 OutputValue struct {
Name string
}
func (OutputValue) inStackConfigSigil() {}
func (OutputValue) inStackInstanceSigil() {}
func (v OutputValue) String() string {
return "output." + v.Name
}
func (v OutputValue) UniqueKey() collections.UniqueKey[OutputValue] {
return v
}
// An OutputValue is its own [collections.UniqueKey].
func (OutputValue) IsUniqueKey(OutputValue) {}
// ConfigOutputValue places an [OutputValue] in the context of a particular [Stack].
type ConfigOutputValue = InStackConfig[OutputValue]
// AbsOutputValue places an [OutputValue] in the context of a particular [StackInstance].
type AbsOutputValue = InStackInstance[OutputValue]
func ParseAbsOutputValueStr(s string) (AbsOutputValue, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
traversal, hclDiags := hclsyntax.ParseTraversalAbs([]byte(s), "", hcl.InitialPos)
diags = diags.Append(hclDiags)
if diags.HasErrors() {
return AbsOutputValue{}, diags
}
ret, moreDiags := ParseAbsOutputValue(traversal)
return ret, diags.Append(moreDiags)
}
func ParseAbsOutputValue(traversal hcl.Traversal) (AbsOutputValue, tfdiags.Diagnostics) {
if traversal.IsRelative() {
// This is always a caller bug: caller must only pass absolute
// traversals in here.
panic("ParseAbsOutputValue with relative traversal")
}
stackInst, remain, diags := parseInStackInstancePrefix(traversal)
if diags.HasErrors() {
return AbsOutputValue{}, diags
}
if len(remain) != 2 {
// it must be output.name, no more and no less.
return AbsOutputValue{}, diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid output address",
Detail: "The output address must be the keyword \"output\" followed by an output name.",
Subject: traversal.SourceRange().Ptr(),
})
}
if kwStep, ok := remain[0].(hcl.TraverseAttr); !ok || kwStep.Name != "output" {
return AbsOutputValue{}, diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid output address",
Detail: "The output address must be the keyword \"output\" followed by an output name.",
Subject: remain[0].SourceRange().Ptr(),
})
}
nameStep, ok := remain[1].(hcl.TraverseAttr)
if !ok {
return AbsOutputValue{}, diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid output address",
Detail: "The output address must be the keyword \"output\" followed by an output name.",
Subject: remain[1].SourceRange().Ptr(),
})
}
return AbsOutputValue{
Stack: stackInst,
Item: OutputValue{
Name: nameStep.Name,
},
}, diags
}