aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/hcl2/hcl/expr_unwrap.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/hcl2/hcl/expr_unwrap.go')
-rw-r--r--vendor/github.com/hashicorp/hcl2/hcl/expr_unwrap.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hcl2/hcl/expr_unwrap.go b/vendor/github.com/hashicorp/hcl2/hcl/expr_unwrap.go
new file mode 100644
index 0000000..6d5d205
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl2/hcl/expr_unwrap.go
@@ -0,0 +1,68 @@
1package hcl
2
3type unwrapExpression interface {
4 UnwrapExpression() Expression
5}
6
7// UnwrapExpression removes any "wrapper" expressions from the given expression,
8// to recover the representation of the physical expression given in source
9// code.
10//
11// Sometimes wrapping expressions are used to modify expression behavior, e.g.
12// in extensions that need to make some local variables available to certain
13// sub-trees of the configuration. This can make it difficult to reliably
14// type-assert on the physical AST types used by the underlying syntax.
15//
16// Unwrapping an expression may modify its behavior by stripping away any
17// additional constraints or capabilities being applied to the Value and
18// Variables methods, so this function should generally only be used prior
19// to operations that concern themselves with the static syntax of the input
20// configuration, and not with the effective value of the expression.
21//
22// Wrapper expression types must support unwrapping by implementing a method
23// called UnwrapExpression that takes no arguments and returns the embedded
24// Expression. Implementations of this method should peel away only one level
25// of wrapping, if multiple are present. This method may return nil to
26// indicate _dynamically_ that no wrapped expression is available, for
27// expression types that might only behave as wrappers in certain cases.
28func UnwrapExpression(expr Expression) Expression {
29 for {
30 unwrap, wrapped := expr.(unwrapExpression)
31 if !wrapped {
32 return expr
33 }
34 innerExpr := unwrap.UnwrapExpression()
35 if innerExpr == nil {
36 return expr
37 }
38 expr = innerExpr
39 }
40}
41
42// UnwrapExpressionUntil is similar to UnwrapExpression except it gives the
43// caller an opportunity to test each level of unwrapping to see each a
44// particular expression is accepted.
45//
46// This could be used, for example, to unwrap until a particular other
47// interface is satisfied, regardless of wrap wrapping level it is satisfied
48// at.
49//
50// The given callback function must return false to continue wrapping, or
51// true to accept and return the proposed expression given. If the callback
52// function rejects even the final, physical expression then the result of
53// this function is nil.
54func UnwrapExpressionUntil(expr Expression, until func(Expression) bool) Expression {
55 for {
56 if until(expr) {
57 return expr
58 }
59 unwrap, wrapped := expr.(unwrapExpression)
60 if !wrapped {
61 return nil
62 }
63 expr = unwrap.UnwrapExpression()
64 if expr == nil {
65 return nil
66 }
67 }
68}