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  }