| // Copyright IBM Corp. 2014, 2026 | |
| // SPDX-License-Identifier: BUSL-1.1 | |
| package namedvals | |
| import ( | |
| "sync" | |
| "github.com/zclconf/go-cty/cty" | |
| "github.com/hashicorp/terraform/internal/addrs" | |
| ) | |
| // State is the main type in this package, representing the current state of | |
| // evaluation that can be mutated as Terraform Core visits different graph | |
| // nodes and then queried to find values that were already resolved earlier | |
| // in the graph walk. | |
| // | |
| // Instances of this type are concurrency-safe so callers do not need to | |
| // implement their own locking when reading and writing from named value | |
| // state. | |
| type State struct { | |
| mu sync.Mutex | |
| variables inputVariableValues | |
| locals localValues | |
| outputs outputValues | |
| } | |
| func NewState() *State { | |
| return &State{ | |
| variables: newValues[addrs.InputVariable, addrs.AbsInputVariableInstance](), | |
| locals: newValues[addrs.LocalValue, addrs.AbsLocalValue](), | |
| outputs: newValues[addrs.OutputValue, addrs.AbsOutputValue](), | |
| } | |
| } | |
| func (s *State) SetInputVariableValue(addr addrs.AbsInputVariableInstance, val cty.Value) { | |
| s.mu.Lock() | |
| s.variables.SetExactResult(addr, val) | |
| s.mu.Unlock() | |
| } | |
| func (s *State) GetInputVariableValue(addr addrs.AbsInputVariableInstance) cty.Value { | |
| s.mu.Lock() | |
| defer s.mu.Unlock() | |
| return s.variables.GetExactResult(addr) | |
| } | |
| func (s *State) HasInputVariableValue(addr addrs.AbsInputVariableInstance) bool { | |
| s.mu.Lock() | |
| defer s.mu.Unlock() | |
| return s.variables.HasExactResult(addr) | |
| } | |
| func (s *State) SetInputVariablePlaceholder(addr addrs.InPartialExpandedModule[addrs.InputVariable], val cty.Value) { | |
| s.mu.Lock() | |
| s.variables.SetPlaceholderResult(addr, val) | |
| s.mu.Unlock() | |
| } | |
| func (s *State) GetInputVariablePlaceholder(addr addrs.InPartialExpandedModule[addrs.InputVariable]) cty.Value { | |
| s.mu.Lock() | |
| defer s.mu.Unlock() | |
| return s.variables.GetPlaceholderResult(addr) | |
| } | |
| func (s *State) SetLocalValue(addr addrs.AbsLocalValue, val cty.Value) { | |
| s.mu.Lock() | |
| s.locals.SetExactResult(addr, val) | |
| s.mu.Unlock() | |
| } | |
| func (s *State) GetLocalValue(addr addrs.AbsLocalValue) cty.Value { | |
| s.mu.Lock() | |
| defer s.mu.Unlock() | |
| return s.locals.GetExactResult(addr) | |
| } | |
| func (s *State) HasLocalValue(addr addrs.AbsLocalValue) bool { | |
| s.mu.Lock() | |
| defer s.mu.Unlock() | |
| return s.locals.HasExactResult(addr) | |
| } | |
| func (s *State) SetLocalValuePlaceholder(addr addrs.InPartialExpandedModule[addrs.LocalValue], val cty.Value) { | |
| s.mu.Lock() | |
| s.locals.SetPlaceholderResult(addr, val) | |
| s.mu.Unlock() | |
| } | |
| func (s *State) GetLocalValuePlaceholder(addr addrs.InPartialExpandedModule[addrs.LocalValue]) cty.Value { | |
| s.mu.Lock() | |
| defer s.mu.Unlock() | |
| return s.locals.GetPlaceholderResult(addr) | |
| } | |
| func (s *State) SetOutputValue(addr addrs.AbsOutputValue, val cty.Value) { | |
| s.mu.Lock() | |
| s.outputs.SetExactResult(addr, val) | |
| s.mu.Unlock() | |
| } | |
| func (s *State) GetOutputValue(addr addrs.AbsOutputValue) cty.Value { | |
| s.mu.Lock() | |
| defer s.mu.Unlock() | |
| return s.outputs.GetExactResult(addr) | |
| } | |
| func (s *State) HasOutputValue(addr addrs.AbsOutputValue) bool { | |
| s.mu.Lock() | |
| defer s.mu.Unlock() | |
| return s.outputs.HasExactResult(addr) | |
| } | |
| func (s *State) SetOutputValuePlaceholder(addr addrs.InPartialExpandedModule[addrs.OutputValue], val cty.Value) { | |
| s.mu.Lock() | |
| s.outputs.SetPlaceholderResult(addr, val) | |
| s.mu.Unlock() | |
| } | |
| func (s *State) GetOutputValuePlaceholder(addr addrs.InPartialExpandedModule[addrs.OutputValue]) cty.Value { | |
| s.mu.Lock() | |
| defer s.mu.Unlock() | |
| return s.outputs.GetPlaceholderResult(addr) | |
| } |