github.com/hashicorp/terraform-plugin-sdk@v1.17.2/terraform/eval_local.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 6 "github.com/hashicorp/hcl/v2" 7 "github.com/zclconf/go-cty/cty" 8 9 "github.com/hashicorp/terraform-plugin-sdk/internal/addrs" 10 "github.com/hashicorp/terraform-plugin-sdk/internal/lang" 11 "github.com/hashicorp/terraform-plugin-sdk/internal/tfdiags" 12 ) 13 14 // EvalLocal is an EvalNode implementation that evaluates the 15 // expression for a local value and writes it into a transient part of 16 // the state. 17 type EvalLocal struct { 18 Addr addrs.LocalValue 19 Expr hcl.Expression 20 } 21 22 func (n *EvalLocal) Eval(ctx EvalContext) (interface{}, error) { 23 var diags tfdiags.Diagnostics 24 25 // We ignore diags here because any problems we might find will be found 26 // again in EvaluateExpr below. 27 refs, _ := lang.ReferencesInExpr(n.Expr) 28 for _, ref := range refs { 29 if ref.Subject == n.Addr { 30 diags = diags.Append(&hcl.Diagnostic{ 31 Severity: hcl.DiagError, 32 Summary: "Self-referencing local value", 33 Detail: fmt.Sprintf("Local value %s cannot use its own result as part of its expression.", n.Addr), 34 Subject: ref.SourceRange.ToHCL().Ptr(), 35 Context: n.Expr.Range().Ptr(), 36 }) 37 } 38 } 39 if diags.HasErrors() { 40 return nil, diags.Err() 41 } 42 43 val, moreDiags := ctx.EvaluateExpr(n.Expr, cty.DynamicPseudoType, nil) 44 diags = diags.Append(moreDiags) 45 if moreDiags.HasErrors() { 46 return nil, diags.Err() 47 } 48 49 state := ctx.State() 50 if state == nil { 51 return nil, fmt.Errorf("cannot write local value to nil state") 52 } 53 54 state.SetLocalValue(n.Addr.Absolute(ctx.Path()), val) 55 56 return nil, nil 57 } 58 59 // EvalDeleteLocal is an EvalNode implementation that deletes a Local value 60 // from the state. Locals aren't persisted, but we don't need to evaluate them 61 // during destroy. 62 type EvalDeleteLocal struct { 63 Addr addrs.LocalValue 64 } 65 66 func (n *EvalDeleteLocal) Eval(ctx EvalContext) (interface{}, error) { 67 state := ctx.State() 68 if state == nil { 69 return nil, nil 70 } 71 72 state.RemoveLocalValue(n.Addr.Absolute(ctx.Path())) 73 return nil, nil 74 }