github.com/opentofu/opentofu@v1.7.1/internal/configs/hcl2shim/util.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package hcl2shim 7 8 import ( 9 "github.com/hashicorp/hcl/v2" 10 "github.com/hashicorp/hcl/v2/hclsyntax" 11 ) 12 13 // exprIsNativeQuotedString determines whether the given expression looks like 14 // it's a quoted string in the HCL native syntax. 15 // 16 // This should be used sparingly only for situations where our legacy HCL 17 // decoding would've expected a keyword or reference in quotes but our new 18 // decoding expects the keyword or reference to be provided directly as 19 // an identifier-based expression. 20 func ExprIsNativeQuotedString(expr hcl.Expression) bool { 21 _, ok := expr.(*hclsyntax.TemplateExpr) 22 return ok 23 } 24 25 // schemaForOverrides takes a *hcl.BodySchema and produces a new one that is 26 // equivalent except that any required attributes are forced to not be required. 27 // 28 // This is useful for dealing with "override" config files, which are allowed 29 // to omit things that they don't wish to override from the main configuration. 30 // 31 // The returned schema may have some pointers in common with the given schema, 32 // so neither the given schema nor the returned schema should be modified after 33 // using this function in order to avoid confusion. 34 // 35 // Overrides are rarely used, so it's recommended to just create the override 36 // schema on the fly only when it's needed, rather than storing it in a global 37 // variable as we tend to do for a primary schema. 38 func SchemaForOverrides(schema *hcl.BodySchema) *hcl.BodySchema { 39 ret := &hcl.BodySchema{ 40 Attributes: make([]hcl.AttributeSchema, len(schema.Attributes)), 41 Blocks: schema.Blocks, 42 } 43 44 for i, attrS := range schema.Attributes { 45 ret.Attributes[i] = attrS 46 ret.Attributes[i].Required = false 47 } 48 49 return ret 50 } 51 52 // schemaWithDynamic takes a *hcl.BodySchema and produces a new one that 53 // is equivalent except that it accepts an additional block type "dynamic" with 54 // a single label, used to recognize usage of the HCL dynamic block extension. 55 func schemaWithDynamic(schema *hcl.BodySchema) *hcl.BodySchema { 56 ret := &hcl.BodySchema{ 57 Attributes: schema.Attributes, 58 Blocks: make([]hcl.BlockHeaderSchema, len(schema.Blocks), len(schema.Blocks)+1), 59 } 60 61 copy(ret.Blocks, schema.Blocks) 62 ret.Blocks = append(ret.Blocks, hcl.BlockHeaderSchema{ 63 Type: "dynamic", 64 LabelNames: []string{"type"}, 65 }) 66 67 return ret 68 }