github.com/terraform-linters/tflint@v0.51.2-0.20240520175844-3750771571b6/terraform/tfhcl/iteration.go (about) 1 package tfhcl 2 3 import ( 4 "github.com/hashicorp/hcl/v2" 5 "github.com/zclconf/go-cty/cty" 6 ) 7 8 type dynamicIteration struct { 9 IteratorName string 10 Key cty.Value 11 Value cty.Value 12 Inherited map[string]*dynamicIteration 13 } 14 15 func (i *dynamicIteration) Object() cty.Value { 16 return cty.ObjectVal(map[string]cty.Value{ 17 "key": i.Key, 18 "value": i.Value, 19 }) 20 } 21 22 func (i *dynamicIteration) EvalContext(base *hcl.EvalContext) *hcl.EvalContext { 23 new := base.NewChild() 24 25 if i != nil { 26 new.Variables = map[string]cty.Value{} 27 for name, otherIt := range i.Inherited { 28 new.Variables[name] = otherIt.Object() 29 } 30 new.Variables[i.IteratorName] = i.Object() 31 } 32 33 return new 34 } 35 36 func (i *dynamicIteration) MakeChild(iteratorName string, key, value cty.Value) *dynamicIteration { 37 if i == nil { 38 // Create entirely new root iteration, then 39 return &dynamicIteration{ 40 IteratorName: iteratorName, 41 Key: key, 42 Value: value, 43 } 44 } 45 46 inherited := map[string]*dynamicIteration{} 47 for name, otherIt := range i.Inherited { 48 inherited[name] = otherIt 49 } 50 inherited[i.IteratorName] = i 51 return &dynamicIteration{ 52 IteratorName: iteratorName, 53 Key: key, 54 Value: value, 55 Inherited: inherited, 56 } 57 } 58 59 type metaArgIteration struct { 60 Count bool 61 Index cty.Value 62 63 ForEach bool 64 Key cty.Value 65 Value cty.Value 66 } 67 68 func MakeCountIteration(index cty.Value) *metaArgIteration { 69 return &metaArgIteration{ 70 Count: true, 71 Index: index, 72 } 73 } 74 75 func MakeForEachIteration(key, value cty.Value) *metaArgIteration { 76 return &metaArgIteration{ 77 ForEach: true, 78 Key: key, 79 Value: value, 80 } 81 } 82 83 func (i *metaArgIteration) EvalContext(base *hcl.EvalContext) *hcl.EvalContext { 84 new := base.NewChild() 85 86 if i != nil { 87 new.Variables = map[string]cty.Value{} 88 89 if i.Count { 90 new.Variables["count"] = cty.ObjectVal(map[string]cty.Value{ 91 "index": i.Index, 92 }) 93 } 94 if i.ForEach { 95 new.Variables["each"] = cty.ObjectVal(map[string]cty.Value{ 96 "key": i.Key, 97 "value": i.Value, 98 }) 99 } 100 } 101 102 return new 103 }