github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/configs/hcl2shim/single_attr_body.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package hcl2shim 5 6 import ( 7 "fmt" 8 9 hcl2 "github.com/hashicorp/hcl/v2" 10 ) 11 12 // SingleAttrBody is a weird implementation of hcl2.Body that acts as if 13 // it has a single attribute whose value is the given expression. 14 // 15 // This is used to shim Resource.RawCount and Output.RawConfig to behave 16 // more like they do in the old HCL loader. 17 type SingleAttrBody struct { 18 Name string 19 Expr hcl2.Expression 20 } 21 22 var _ hcl2.Body = SingleAttrBody{} 23 24 func (b SingleAttrBody) Content(schema *hcl2.BodySchema) (*hcl2.BodyContent, hcl2.Diagnostics) { 25 content, all, diags := b.content(schema) 26 if !all { 27 // This should never happen because this body implementation should only 28 // be used by code that is aware that it's using a single-attr body. 29 diags = append(diags, &hcl2.Diagnostic{ 30 Severity: hcl2.DiagError, 31 Summary: "Invalid attribute", 32 Detail: fmt.Sprintf("The correct attribute name is %q.", b.Name), 33 Subject: b.Expr.Range().Ptr(), 34 }) 35 } 36 return content, diags 37 } 38 39 func (b SingleAttrBody) PartialContent(schema *hcl2.BodySchema) (*hcl2.BodyContent, hcl2.Body, hcl2.Diagnostics) { 40 content, all, diags := b.content(schema) 41 var remain hcl2.Body 42 if all { 43 // If the request matched the one attribute we represent, then the 44 // remaining body is empty. 45 remain = hcl2.EmptyBody() 46 } else { 47 remain = b 48 } 49 return content, remain, diags 50 } 51 52 func (b SingleAttrBody) content(schema *hcl2.BodySchema) (*hcl2.BodyContent, bool, hcl2.Diagnostics) { 53 ret := &hcl2.BodyContent{} 54 all := false 55 var diags hcl2.Diagnostics 56 57 for _, attrS := range schema.Attributes { 58 if attrS.Name == b.Name { 59 attrs, _ := b.JustAttributes() 60 ret.Attributes = attrs 61 all = true 62 } else if attrS.Required { 63 diags = append(diags, &hcl2.Diagnostic{ 64 Severity: hcl2.DiagError, 65 Summary: "Missing attribute", 66 Detail: fmt.Sprintf("The attribute %q is required.", attrS.Name), 67 Subject: b.Expr.Range().Ptr(), 68 }) 69 } 70 } 71 72 return ret, all, diags 73 } 74 75 func (b SingleAttrBody) JustAttributes() (hcl2.Attributes, hcl2.Diagnostics) { 76 return hcl2.Attributes{ 77 b.Name: { 78 Expr: b.Expr, 79 Name: b.Name, 80 NameRange: b.Expr.Range(), 81 Range: b.Expr.Range(), 82 }, 83 }, nil 84 } 85 86 func (b SingleAttrBody) MissingItemRange() hcl2.Range { 87 return b.Expr.Range() 88 }