The previous approach had the problem that we only had the
CompiledModuleInstance object for a child module briefly in a local
variable while evaluating the child call, which is sufficient for just
evaluation but is not enough to support full config tree traversal for
questions like "what resource instances are declared throughout the
configuration?" and "what configgraph node corresponds to this provider
configuration instance address?"
This moves the separation of concerns around a little to be perhaps more
like how resource instances work, where the ModuleCallInstance.Value
method just wraps a function provided by the "compile" layer which then
takes the config value and compiles the child module instance.
This means that the "compile" layer can then hold on to the
CompiledModuleInstance object for the child module instance as part of
the "glue" in the ModuleCallInstance object and then use it to deal with
the config-tree-traversing methods in its own CompiledModuleInstance
implementation.
The new test of ConfigInstance.PrepareToPlan in lang/eval illustrates that
the system is now finally able to walk the whole configuration tree to find
resource instances and the provider instances they depend on.
(The handling of inheritance of providers between parent and child module
instances is still not working like the current system does, because the
"providers sidechannel" mechanism remains incomplete.
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
There's now enough here to produce a data structure where each ephemeral
resource instance is associated with all of the resource instances that
must complete planning before it can be closed.
This also doubles as the first demonstration of dynamic analysis of
resource instance dependencies using cty marks, with
TestPrepare_ephemeralResourceUsers illustrating the more precise results.
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
In "package tofu" today we try to do everything using a generic acyclic
graph model and generic graph walk, which _works_ but tends to make every
other part of the problem very hard to follow because we rely a lot on
sidecar shared mutable data structures to propagate results between the
isolated operations.
This is the beginning of an experimental new way to do it where the "graph"
is implied by a model that more closely represents how the language itself
works, with explicit modelling of the relationships between different
types of objects and letting results flow directly from one object to
another without any big shared mutable state.
There's still a lot to do before this is actually complete enough to
evaluate whether it's a viable new design, but I'm considering this a good
starting checkpoint since there's enough here to run a simple test of
propagating data all the way from input variables to output values via
intermediate local values.
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
This package provides a more generic version of what's currently modeled
by the likes of lang.Scope and lang.Data, designed to avoid having a huge
single type that must know about everything in the language and, for this
package's purposes alone, to avoid knowing anything about the language at
all except that it uses HCL.
This is currently just an experiment not used by anything, and so is dead
code aside from the contrived mini-language implemented in example_test.go.
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>