blob: ed26d0cdfc1f1f7ca7b4882932bebb097fca1c55 [file] [log] [blame] [edit]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package stackaddrs
import (
"fmt"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/collections"
"github.com/hashicorp/terraform/internal/tfdiags"
)
// InConfigComponent represents addresses of objects that belong to the modules
// associated with a particular component.
//
// Although the type parameter is rather unconstrained, it doesn't make sense to
// use this for types other than those from package addrs that represent
// configuration constructs, like [addrs.ConfigResource], etc.
type InConfigComponent[T InComponentable] struct {
Component ConfigComponent
Item T
}
// ConfigResource represents a resource configuration from inside a
// particular component.
type ConfigResource = InConfigComponent[addrs.ConfigResource]
// ConfigModule represents a module from inside a particular component.
//
// Note that the string representation of the address of the root module of
// a component is identical to the string representation of the component
// address alone.
type ConfigModule = InConfigComponent[addrs.Module]
func (c InConfigComponent[T]) String() string {
itemStr := c.Item.String()
componentStr := c.Component.String()
if itemStr == "" {
return componentStr
}
return componentStr + "." + itemStr
}
// UniqueKey implements collections.UniqueKeyer.
func (c InConfigComponent[T]) UniqueKey() collections.UniqueKey[InConfigComponent[T]] {
return inConfigComponentKey[T]{
componentKey: c.Component.UniqueKey(),
itemKey: c.Item.UniqueKey(),
}
}
type inConfigComponentKey[T InComponentable] struct {
componentKey collections.UniqueKey[ConfigComponent]
itemKey addrs.UniqueKey
}
// IsUniqueKey implements collections.UniqueKey.
func (inConfigComponentKey[T]) IsUniqueKey(InConfigComponent[T]) {}
// InAbsComponentInstance represents addresses of objects that belong to the module
// instances associated with a particular component instance.
//
// Although the type parameter is rather unconstrained, it doesn't make sense to
// use this for types other than those from package addrs that represent
// objects that can belong to Terraform modules, like
// [addrs.AbsResourceInstance], etc.
type InAbsComponentInstance[T InComponentable] struct {
Component AbsComponentInstance
Item T
}
// AbsResource represents a not-yet-expanded resource from inside a particular
// component instance.
type AbsResource = InAbsComponentInstance[addrs.AbsResource]
var _ collections.UniqueKeyer[AbsResource] = AbsResource{}
// AbsResourceInstance represents an instance of a resource from inside a
// particular component instance.
type AbsResourceInstance = InAbsComponentInstance[addrs.AbsResourceInstance]
// AbsResourceInstanceObject represents an object associated with an instance
// of a resource from inside a particular component instance.
type AbsResourceInstanceObject = InAbsComponentInstance[addrs.AbsResourceInstanceObject]
// AbsModuleInstance represents an instance of a module from inside a
// particular component instance.
//
// Note that the string representation of the address of the root module of
// a component instance is identical to the string representation of the
// component instance address alone.
type AbsModuleInstance = InAbsComponentInstance[addrs.ModuleInstance]
func (c InAbsComponentInstance[T]) String() string {
itemStr := c.Item.String()
componentStr := c.Component.String()
if itemStr == "" {
return componentStr
}
return componentStr + "." + itemStr
}
// UniqueKey implements collections.UniqueKeyer.
func (c InAbsComponentInstance[T]) UniqueKey() collections.UniqueKey[InAbsComponentInstance[T]] {
return inAbsComponentInstanceKey[T]{
componentKey: c.Component.UniqueKey(),
itemKey: c.Item.UniqueKey(),
}
}
type inAbsComponentInstanceKey[T InComponentable] struct {
componentKey collections.UniqueKey[AbsComponentInstance]
itemKey addrs.UniqueKey
}
// IsUniqueKey implements collections.UniqueKey.
func (inAbsComponentInstanceKey[T]) IsUniqueKey(InAbsComponentInstance[T]) {}
// InComponentable just embeds the interfaces that we require for the type
// parameters of both the [InConfigComponent] and [InAbsComponent] types.
type InComponentable interface {
addrs.UniqueKeyer
fmt.Stringer
}
func ParseAbsResourceInstanceObject(traversal hcl.Traversal) (AbsResourceInstanceObject, tfdiags.Diagnostics) {
stack, remain, diags := ParseAbsComponentInstanceOnly(traversal)
if diags.HasErrors() {
return AbsResourceInstanceObject{}, diags
}
resource, diags := addrs.ParseAbsResourceInstance(remain)
if diags.HasErrors() {
return AbsResourceInstanceObject{}, diags
}
return AbsResourceInstanceObject{
Component: stack,
Item: addrs.AbsResourceInstanceObject{
ResourceInstance: resource,
},
}, diags
}
func ParseAbsResourceInstanceObjectStr(s string) (AbsResourceInstanceObject, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
traversal, hclDiags := hclsyntax.ParseTraversalAbs([]byte(s), "", hcl.InitialPos)
diags = diags.Append(hclDiags)
if diags.HasErrors() {
return AbsResourceInstanceObject{}, diags
}
ret, moreDiags := ParseAbsResourceInstanceObject(traversal)
diags = diags.Append(moreDiags)
return ret, diags
}