| package blocktoattr |
| |
| import ( |
| "github.com/hashicorp/hcl/v2" |
| "github.com/hashicorp/hcl/v2/ext/dynblock" |
| "github.com/hashicorp/hcl/v2/hcldec" |
| "github.com/hashicorp/terraform/internal/configs/configschema" |
| ) |
| |
| // ExpandedVariables finds all of the global variables referenced in the |
| // given body with the given schema while taking into account the possibilities |
| // both of "dynamic" blocks being expanded and the possibility of certain |
| // attributes being written instead as nested blocks as allowed by the |
| // FixUpBlockAttrs function. |
| // |
| // This function exists to allow variables to be analyzed prior to dynamic |
| // block expansion while also dealing with the fact that dynamic block expansion |
| // might in turn produce nested blocks that are subject to FixUpBlockAttrs. |
| // |
| // This is intended as a drop-in replacement for dynblock.VariablesHCLDec, |
| // which is itself a drop-in replacement for hcldec.Variables. |
| func ExpandedVariables(body hcl.Body, schema *configschema.Block) []hcl.Traversal { |
| rootNode := dynblock.WalkVariables(body) |
| return walkVariables(rootNode, body, schema) |
| } |
| |
| func walkVariables(node dynblock.WalkVariablesNode, body hcl.Body, schema *configschema.Block) []hcl.Traversal { |
| givenRawSchema := hcldec.ImpliedSchema(schema.DecoderSpec()) |
| ambiguousNames := ambiguousNames(schema) |
| effectiveRawSchema := effectiveSchema(givenRawSchema, body, ambiguousNames, false) |
| vars, children := node.Visit(effectiveRawSchema) |
| |
| for _, child := range children { |
| if blockS, exists := schema.BlockTypes[child.BlockTypeName]; exists { |
| vars = append(vars, walkVariables(child.Node, child.Body(), &blockS.Block)...) |
| } else if attrS, exists := schema.Attributes[child.BlockTypeName]; exists && attrS.Type.IsCollectionType() && attrS.Type.ElementType().IsObjectType() { |
| // ☝️Check for collection type before element type, because if this is a mis-placed reference, |
| // a panic here will prevent other useful diags from being elevated to show the user what to fix |
| synthSchema := SchemaForCtyElementType(attrS.Type.ElementType()) |
| vars = append(vars, walkVariables(child.Node, child.Body(), synthSchema)...) |
| } |
| } |
| |
| return vars |
| } |