]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/lang/references.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / lang / references.go
1 package lang
2
3 import (
4 "github.com/hashicorp/hcl2/hcl"
5 "github.com/hashicorp/terraform/addrs"
6 "github.com/hashicorp/terraform/configs/configschema"
7 "github.com/hashicorp/terraform/lang/blocktoattr"
8 "github.com/hashicorp/terraform/tfdiags"
9 )
10
11 // References finds all of the references in the given set of traversals,
12 // returning diagnostics if any of the traversals cannot be interpreted as a
13 // reference.
14 //
15 // This function does not do any de-duplication of references, since references
16 // have source location information embedded in them and so any invalid
17 // references that are duplicated should have errors reported for each
18 // occurence.
19 //
20 // If the returned diagnostics contains errors then the result may be
21 // incomplete or invalid. Otherwise, the returned slice has one reference per
22 // given traversal, though it is not guaranteed that the references will
23 // appear in the same order as the given traversals.
24 func References(traversals []hcl.Traversal) ([]*addrs.Reference, tfdiags.Diagnostics) {
25 if len(traversals) == 0 {
26 return nil, nil
27 }
28
29 var diags tfdiags.Diagnostics
30 refs := make([]*addrs.Reference, 0, len(traversals))
31
32 for _, traversal := range traversals {
33 ref, refDiags := addrs.ParseRef(traversal)
34 diags = diags.Append(refDiags)
35 if ref == nil {
36 continue
37 }
38 refs = append(refs, ref)
39 }
40
41 return refs, diags
42 }
43
44 // ReferencesInBlock is a helper wrapper around References that first searches
45 // the given body for traversals, before converting those traversals to
46 // references.
47 //
48 // A block schema must be provided so that this function can determine where in
49 // the body variables are expected.
50 func ReferencesInBlock(body hcl.Body, schema *configschema.Block) ([]*addrs.Reference, tfdiags.Diagnostics) {
51 if body == nil {
52 return nil, nil
53 }
54
55 // We use blocktoattr.ExpandedVariables instead of hcldec.Variables or
56 // dynblock.VariablesHCLDec here because when we evaluate a block we'll
57 // first apply the dynamic block extension and _then_ the blocktoattr
58 // transform, and so blocktoattr.ExpandedVariables takes into account
59 // both of those transforms when it analyzes the body to ensure we find
60 // all of the references as if they'd already moved into their final
61 // locations, even though we can't expand dynamic blocks yet until we
62 // already know which variables are required.
63 //
64 // The set of cases we want to detect here is covered by the tests for
65 // the plan graph builder in the main 'terraform' package, since it's
66 // in a better position to test this due to having mock providers etc
67 // available.
68 traversals := blocktoattr.ExpandedVariables(body, schema)
69 return References(traversals)
70 }
71
72 // ReferencesInExpr is a helper wrapper around References that first searches
73 // the given expression for traversals, before converting those traversals
74 // to references.
75 func ReferencesInExpr(expr hcl.Expression) ([]*addrs.Reference, tfdiags.Diagnostics) {
76 if expr == nil {
77 return nil, nil
78 }
79 traversals := expr.Variables()
80 return References(traversals)
81 }