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  }