diff --git a/addrs/count_attr.go b/addrs/count_attr.go index 3287083ac..90a5faf0e 100644 --- a/addrs/count_attr.go +++ b/addrs/count_attr.go @@ -6,3 +6,7 @@ type CountAttr struct { referenceable Name string } + +func (ca CountAttr) String() string { + return "count." + ca.Name +} diff --git a/addrs/input_variable.go b/addrs/input_variable.go index 1b4cb59d1..ad4370bb8 100644 --- a/addrs/input_variable.go +++ b/addrs/input_variable.go @@ -5,3 +5,7 @@ type InputVariable struct { referenceable Name string } + +func (v InputVariable) String() string { + return "var." + v.Name +} diff --git a/addrs/instance_key.go b/addrs/instance_key.go index f970c0f80..41576c0b6 100644 --- a/addrs/instance_key.go +++ b/addrs/instance_key.go @@ -17,6 +17,7 @@ import ( // InstanceKey. type InstanceKey interface { instanceKeySigil() + String() string } // ParseInstanceKey returns the instance key corresponding to the given value, @@ -51,9 +52,19 @@ type IntKey int func (k IntKey) instanceKeySigil() { } +func (k IntKey) String() string { + return fmt.Sprintf("[%d]", int(k)) +} + // StringKey is the InstanceKey representation representing string indices, as // used when the "for_each" argument is specified with a map or object type. type StringKey string func (k StringKey) instanceKeySigil() { } + +func (k StringKey) String() string { + // FIXME: This isn't _quite_ right because Go's quoted string syntax is + // slightly different than HCL's, but we'll accept it for now. + return fmt.Sprintf("[%q]", string(k)) +} diff --git a/addrs/local_value.go b/addrs/local_value.go index 939045a53..c02036e0f 100644 --- a/addrs/local_value.go +++ b/addrs/local_value.go @@ -5,3 +5,7 @@ type LocalValue struct { referenceable Name string } + +func (v LocalValue) String() string { + return "local." + v.Name +} diff --git a/addrs/module_call.go b/addrs/module_call.go index 0b7276ad1..bbbd76685 100644 --- a/addrs/module_call.go +++ b/addrs/module_call.go @@ -1,5 +1,9 @@ package addrs +import ( + "fmt" +) + // ModuleCall is the address of a call from the current module to a child // module. // @@ -10,6 +14,10 @@ type ModuleCall struct { Name string } +func (c ModuleCall) String() string { + return "module." + c.Name +} + // Instance returns the address of an instance of the receiver identified by // the given key. func (c ModuleCall) Instance(key InstanceKey) ModuleCallInstance { @@ -28,6 +36,13 @@ type ModuleCallInstance struct { Key InstanceKey } +func (c ModuleCallInstance) String() string { + if c.Key == NoKey { + return c.Call.String() + } + return fmt.Sprintf("module.%s%s", c.Call.Name, c.Key) +} + // Output returns the address of an output of the receiver identified by its // name. func (c ModuleCallInstance) Output(name string) ModuleCallOutput { @@ -44,3 +59,7 @@ type ModuleCallOutput struct { Call ModuleCallInstance Name string } + +func (co ModuleCallOutput) String() string { + return fmt.Sprintf("%s.%s", co.Call.String(), co.Name) +} diff --git a/addrs/path_attr.go b/addrs/path_attr.go index 77c9110b4..cfc13f4bc 100644 --- a/addrs/path_attr.go +++ b/addrs/path_attr.go @@ -6,3 +6,7 @@ type PathAttr struct { referenceable Name string } + +func (pa PathAttr) String() string { + return "path." + pa.Name +} diff --git a/addrs/referenceable.go b/addrs/referenceable.go index b3bb1a9fb..211083a5f 100644 --- a/addrs/referenceable.go +++ b/addrs/referenceable.go @@ -3,7 +3,14 @@ package addrs // Referenceable is an interface implemented by all address types that can // appear as references in configuration language expressions. type Referenceable interface { + // All implementations of this interface must be covered by the type switch + // in lang.Scope.buildEvalContext. referenceableSigil() + + // String produces a string representation of the address that could be + // parsed as a HCL traversal and passed to ParseRef to produce an identical + // result. + String() string } type referenceable struct { diff --git a/addrs/resource.go b/addrs/resource.go index b88436b6c..18049b04c 100644 --- a/addrs/resource.go +++ b/addrs/resource.go @@ -1,5 +1,9 @@ package addrs +import ( + "fmt" +) + // Resource is an address for a resource block within configuration, which // contains potentially-multiple resource instances if that configuration // block uses "count" or "for_each". @@ -10,6 +14,17 @@ type Resource struct { Name string } +func (r Resource) String() string { + switch r.Mode { + case ManagedResourceMode: + return fmt.Sprintf("%s.%s", r.Type, r.Name) + case DataResourceMode: + return fmt.Sprintf("data.%s.%s", r.Type, r.Name) + default: + panic(fmt.Errorf("resource address with invalid mode %s", r.Mode)) + } +} + // Instance produces the address for a specific instance of the receiver // that is idenfied by the given key. func (r Resource) Instance(key InstanceKey) ResourceInstance { @@ -37,6 +52,13 @@ type ResourceInstance struct { Key InstanceKey } +func (r ResourceInstance) String() string { + if r.Key == NoKey { + return r.Resource.String() + } + return r.Resource.String() + r.Key.String() +} + // Absolute returns an AbsResourceInstance from the receiver and the given module // instance address. func (r ResourceInstance) Absolute(module ModuleInstance) AbsResourceInstance { diff --git a/addrs/self.go b/addrs/self.go index 4439f75cd..7f24eaf08 100644 --- a/addrs/self.go +++ b/addrs/self.go @@ -8,3 +8,7 @@ type selfT int func (s selfT) referenceableSigil() { } + +func (s selfT) String() string { + return "self" +} diff --git a/addrs/terraform_attr.go b/addrs/terraform_attr.go index 3f8f7a98a..a880182ae 100644 --- a/addrs/terraform_attr.go +++ b/addrs/terraform_attr.go @@ -6,3 +6,7 @@ type TerraformAttr struct { referenceable Name string } + +func (ta TerraformAttr) String() string { + return "terraform." + ta.Name +}