Make the function work specifically how we need for RequiresReplace.
Skip index changes, any set changes are only recorded as the set itself,
and filter out duplicate paths.
Add a few more tests to check for various nested structures.
Rather than try and make a generalized path function here, what we
really need in a function to generate the paths needed for
RequiresReplace. This needs to take into account that sets elements
don't need to be indexed themselves, and changes to collection index
values aren't needed.
PathFromFlatmapKey is used to convert a flatmap key to a cty.Path, and
ensures it conforms to the type schema.
This is used when handling Diffs, where the ResourceAttrDiffs are
indexed by the flatmapped key values, and we need to convert those to
addresses to apply to a cty.Value.
When creating a flatmap from a cty.Value, there may be Null collections
which don't need to be added to the flatmap at all. Skip over these to
avoid panicking in ElementIterator with a Null value.
A nil flatmap will be encoded as a NullVal of the correct type. When
Converting a NullVal back to a flatmap, return nil immediately rather
than attempting to build the values.
Previously unknown values were round-tripping through flatmap and coming
out as known strings containing the UnknownVariableValue. (The classic bug
that, ironically, was one of the big reasons to write cty!)
Now we properly handle unknown values in both directions: going in to
flatmap we write UnknownVariableValue at the appropriate key (as the count
for sequences or maps) and then coming out of flatmap we turn
UnknownVariableValue back into a cty unknown value of the requested type.
These particular shims will have a pretty limited lifetime in mainline
Terraform code (primarily to stub out the new expression evaluator against
the old state structs until the new format is implemented) but will live
on for some time in state migration and provider plugin compatibility
shims.
Absent values are omitted by the old code we are emulating in HCL, so we
must do the same here in order to avoid breaking assumptions in the
helper/schema layer.
The value-conversion machinery is also needed in the main "terraform"
package to help us populate our HCL2 evaluation scope, so a subset of the
shim functions move here into a new package where they can be public.
Some of them remain private within the config package since they depend
on some other symbols in the config package, and they are not needed
by outside callers anyway.