opentofu/internal/configs/hcl2shim/single_attr_body.go
Martin Atkins 31349a9c3a Move configs/ to internal/configs/
This is part of a general effort to move all of Terraform's non-library
package surface under internal in order to reinforce that these are for
internal use within Terraform only.

If you were previously importing packages under this prefix into an
external codebase, you could pin to an earlier release tag as an interim
solution until you've make a plan to achieve the same functionality some
other way.
2021-05-17 14:09:07 -07:00

86 lines
2.2 KiB
Go

package hcl2shim
import (
"fmt"
hcl2 "github.com/hashicorp/hcl/v2"
)
// SingleAttrBody is a weird implementation of hcl2.Body that acts as if
// it has a single attribute whose value is the given expression.
//
// This is used to shim Resource.RawCount and Output.RawConfig to behave
// more like they do in the old HCL loader.
type SingleAttrBody struct {
Name string
Expr hcl2.Expression
}
var _ hcl2.Body = SingleAttrBody{}
func (b SingleAttrBody) Content(schema *hcl2.BodySchema) (*hcl2.BodyContent, hcl2.Diagnostics) {
content, all, diags := b.content(schema)
if !all {
// This should never happen because this body implementation should only
// be used by code that is aware that it's using a single-attr body.
diags = append(diags, &hcl2.Diagnostic{
Severity: hcl2.DiagError,
Summary: "Invalid attribute",
Detail: fmt.Sprintf("The correct attribute name is %q.", b.Name),
Subject: b.Expr.Range().Ptr(),
})
}
return content, diags
}
func (b SingleAttrBody) PartialContent(schema *hcl2.BodySchema) (*hcl2.BodyContent, hcl2.Body, hcl2.Diagnostics) {
content, all, diags := b.content(schema)
var remain hcl2.Body
if all {
// If the request matched the one attribute we represent, then the
// remaining body is empty.
remain = hcl2.EmptyBody()
} else {
remain = b
}
return content, remain, diags
}
func (b SingleAttrBody) content(schema *hcl2.BodySchema) (*hcl2.BodyContent, bool, hcl2.Diagnostics) {
ret := &hcl2.BodyContent{}
all := false
var diags hcl2.Diagnostics
for _, attrS := range schema.Attributes {
if attrS.Name == b.Name {
attrs, _ := b.JustAttributes()
ret.Attributes = attrs
all = true
} else if attrS.Required {
diags = append(diags, &hcl2.Diagnostic{
Severity: hcl2.DiagError,
Summary: "Missing attribute",
Detail: fmt.Sprintf("The attribute %q is required.", attrS.Name),
Subject: b.Expr.Range().Ptr(),
})
}
}
return ret, all, diags
}
func (b SingleAttrBody) JustAttributes() (hcl2.Attributes, hcl2.Diagnostics) {
return hcl2.Attributes{
b.Name: {
Expr: b.Expr,
Name: b.Name,
NameRange: b.Expr.Range(),
Range: b.Expr.Range(),
},
}, nil
}
func (b SingleAttrBody) MissingItemRange() hcl2.Range {
return b.Expr.Range()
}