| 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() |
| } |