From 3212f6f3676162ec9e47ba36a12b9460fbb4b10d Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Tue, 29 Jun 2021 15:25:00 -0700 Subject: [PATCH] addrs: AbsModuleCall type Our documentation for ModuleCall originally asserted that we didn't need AbsModuleCall because ModuleInstance captured the same information, but when we added count and for_each for modules we introduced ModuleCallInstance to represent a reference to an instance of a local module call, and now _that_ is the type whose absolute equivalent is ModuleInstance. We previously had no absolute representation of the call itself, without any particular instance. That's what AbsModuleCall now represents, allowing us to be explicit about when we're talking about the module block vs. instances it declares, which is the same distinction represented by AbsResource vs. AbsResourceInstance. Just like with AbsResource and AbsResourceInstance though, there is syntactic ambiguity between a no-key call instance and a whole module call, and so some codepaths might accept both to start and then use other context to dynamically choose a particular interpretation, in which case this distinction becomes meaningful in representing the result of that decision. --- internal/addrs/module_call.go | 48 +++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/internal/addrs/module_call.go b/internal/addrs/module_call.go index bfaf66e96..8d6920774 100644 --- a/internal/addrs/module_call.go +++ b/internal/addrs/module_call.go @@ -6,9 +6,6 @@ import ( // ModuleCall is the address of a call from the current module to a child // module. -// -// There is no "Abs" version of ModuleCall because an absolute module path -// is represented by ModuleInstance. type ModuleCall struct { referenceable Name string @@ -27,9 +24,40 @@ func (c ModuleCall) Instance(key InstanceKey) ModuleCallInstance { } } +func (c ModuleCall) Absolute(moduleAddr ModuleInstance) AbsModuleCall { + return AbsModuleCall{ + Module: moduleAddr, + Call: c, + } +} + +// AbsModuleCall is the address of a "module" block relative to the root +// of the configuration. +// +// This is similar to ModuleInstance alone, but specifically represents +// the module block itself rather than any one of the instances that +// module block declares. +type AbsModuleCall struct { + Module ModuleInstance + Call ModuleCall +} + +func (c AbsModuleCall) Instance(key InstanceKey) ModuleInstance { + ret := make(ModuleInstance, len(c.Module), len(c.Module)+1) + copy(ret, c.Module) + ret = append(ret, ModuleInstanceStep{ + Name: c.Call.Name, + InstanceKey: key, + }) + return ret +} + // ModuleCallInstance is the address of one instance of a module created from // a module call, which might create multiple instances using "count" or // "for_each" arguments. +// +// There is no "Abs" version of ModuleCallInstance because an absolute module +// path is represented by ModuleInstance. type ModuleCallInstance struct { referenceable Call ModuleCall @@ -43,6 +71,16 @@ func (c ModuleCallInstance) String() string { return fmt.Sprintf("module.%s%s", c.Call.Name, c.Key) } +func (c ModuleCallInstance) Absolute(moduleAddr ModuleInstance) ModuleInstance { + ret := make(ModuleInstance, len(moduleAddr), len(moduleAddr)+1) + copy(ret, moduleAddr) + ret = append(ret, ModuleInstanceStep{ + Name: c.Call.Name, + InstanceKey: c.Key, + }) + return ret +} + // ModuleInstance returns the address of the module instance that corresponds // to the receiving call instance when resolved in the given calling module. // In other words, it returns the child module instance that the receving @@ -53,8 +91,8 @@ func (c ModuleCallInstance) ModuleInstance(caller ModuleInstance) ModuleInstance // Output returns the absolute address of an output of the receiver identified by its // name. -func (c ModuleCallInstance) Output(name string) AbsModuleCallOutput { - return AbsModuleCallOutput{ +func (c ModuleCallInstance) Output(name string) ModuleCallInstanceOutput { + return ModuleCallInstanceOutput{ Call: c, Name: name, }