github.com/hashicorp/hcl/v2@v2.20.0/ext/customdecode/customdecode.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 // Package customdecode contains a HCL extension that allows, in certain 5 // contexts, expression evaluation to be overridden by custom static analysis. 6 // 7 // This mechanism is only supported in certain specific contexts where 8 // expressions are decoded with a specific target type in mind. For more 9 // information, see the documentation on CustomExpressionDecoder. 10 package customdecode 11 12 import ( 13 "github.com/hashicorp/hcl/v2" 14 "github.com/zclconf/go-cty/cty" 15 ) 16 17 type customDecoderImpl int 18 19 // CustomExpressionDecoder is a value intended to be used as a cty capsule 20 // type ExtensionData key for capsule types whose values are to be obtained 21 // by static analysis of an expression rather than normal evaluation of that 22 // expression. 23 // 24 // When a cooperating capsule type is asked for ExtensionData with this key, 25 // it must return a non-nil CustomExpressionDecoderFunc value. 26 // 27 // This mechanism is not universally supported; instead, it's handled in a few 28 // specific places where expressions are evaluated with the intent of producing 29 // a cty.Value of a type given by the calling application. 30 // 31 // Specifically, this currently works for type constraints given in 32 // hcldec.AttrSpec and hcldec.BlockAttrsSpec, and it works for arguments to 33 // function calls in the HCL native syntax. HCL extensions implemented outside 34 // of the main HCL module may also implement this; consult their own 35 // documentation for details. 36 const CustomExpressionDecoder = customDecoderImpl(1) 37 38 // CustomExpressionDecoderFunc is the type of value that must be returned by 39 // a capsule type handling the key CustomExpressionDecoder in its ExtensionData 40 // implementation. 41 // 42 // If no error diagnostics are returned, the result value MUST be of the 43 // capsule type that the decoder function was derived from. If the returned 44 // error diagnostics prevent producing a value at all, return cty.NilVal. 45 type CustomExpressionDecoderFunc func(expr hcl.Expression, ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) 46 47 // CustomExpressionDecoderForType takes any cty type and returns its 48 // custom expression decoder implementation if it has one. If it is not a 49 // capsule type or it does not implement a custom expression decoder, this 50 // function returns nil. 51 func CustomExpressionDecoderForType(ty cty.Type) CustomExpressionDecoderFunc { 52 if !ty.IsCapsuleType() { 53 return nil 54 } 55 if fn, ok := ty.CapsuleExtensionData(CustomExpressionDecoder).(CustomExpressionDecoderFunc); ok { 56 return fn 57 } 58 return nil 59 }