3 type unwrapExpression interface {
4 UnwrapExpression() Expression
7 // UnwrapExpression removes any "wrapper" expressions from the given expression,
8 // to recover the representation of the physical expression given in source
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.
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.
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.
28 func UnwrapExpression(expr Expression) Expression {
30 unwrap, wrapped := expr.(unwrapExpression)
34 innerExpr := unwrap.UnwrapExpression()
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.
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
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.
54 func UnwrapExpressionUntil(expr Expression, until func(Expression) bool) Expression {
59 unwrap, wrapped := expr.(unwrapExpression)
63 expr = unwrap.UnwrapExpression()