diff options
author | Alex Pilon <apilon@hashicorp.com> | 2019-02-22 18:24:37 -0500 |
---|---|---|
committer | Alex Pilon <apilon@hashicorp.com> | 2019-02-22 18:24:37 -0500 |
commit | 15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (patch) | |
tree | 255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/hashicorp/terraform/config/hcl2_shim_util.go | |
parent | 07971ca38143c5faf951d152fba370ddcbe26ad5 (diff) | |
download | terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.gz terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.zst terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.zip |
deps: github.com/hashicorp/terraform@sdk-v0.11-with-go-modules
Updated via: go get github.com/hashicorp/terraform@sdk-v0.11-with-go-modules and go mod tidy
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/config/hcl2_shim_util.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/config/hcl2_shim_util.go | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/config/hcl2_shim_util.go b/vendor/github.com/hashicorp/terraform/config/hcl2_shim_util.go new file mode 100644 index 0000000..207d105 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/config/hcl2_shim_util.go | |||
@@ -0,0 +1,134 @@ | |||
1 | package config | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | |||
6 | "github.com/zclconf/go-cty/cty/function/stdlib" | ||
7 | |||
8 | "github.com/hashicorp/hil/ast" | ||
9 | "github.com/hashicorp/terraform/config/hcl2shim" | ||
10 | |||
11 | hcl2 "github.com/hashicorp/hcl2/hcl" | ||
12 | "github.com/zclconf/go-cty/cty" | ||
13 | "github.com/zclconf/go-cty/cty/convert" | ||
14 | "github.com/zclconf/go-cty/cty/function" | ||
15 | ) | ||
16 | |||
17 | // --------------------------------------------------------------------------- | ||
18 | // This file contains some helper functions that are used to shim between | ||
19 | // HCL2 concepts and HCL/HIL concepts, to help us mostly preserve the existing | ||
20 | // public API that was built around HCL/HIL-oriented approaches. | ||
21 | // --------------------------------------------------------------------------- | ||
22 | |||
23 | func hcl2InterpolationFuncs() map[string]function.Function { | ||
24 | hcl2Funcs := map[string]function.Function{} | ||
25 | |||
26 | for name, hilFunc := range Funcs() { | ||
27 | hcl2Funcs[name] = hcl2InterpolationFuncShim(hilFunc) | ||
28 | } | ||
29 | |||
30 | // Some functions in the old world are dealt with inside langEvalConfig | ||
31 | // due to their legacy reliance on direct access to the symbol table. | ||
32 | // Since 0.7 they don't actually need it anymore and just ignore it, | ||
33 | // so we're cheating a bit here and exploiting that detail by passing nil. | ||
34 | hcl2Funcs["lookup"] = hcl2InterpolationFuncShim(interpolationFuncLookup(nil)) | ||
35 | hcl2Funcs["keys"] = hcl2InterpolationFuncShim(interpolationFuncKeys(nil)) | ||
36 | hcl2Funcs["values"] = hcl2InterpolationFuncShim(interpolationFuncValues(nil)) | ||
37 | |||
38 | // As a bonus, we'll provide the JSON-handling functions from the cty | ||
39 | // function library since its "jsonencode" is more complete (doesn't force | ||
40 | // weird type conversions) and HIL's type system can't represent | ||
41 | // "jsondecode" at all. The result of jsondecode will eventually be forced | ||
42 | // to conform to the HIL type system on exit into the rest of Terraform due | ||
43 | // to our shimming right now, but it should be usable for decoding _within_ | ||
44 | // an expression. | ||
45 | hcl2Funcs["jsonencode"] = stdlib.JSONEncodeFunc | ||
46 | hcl2Funcs["jsondecode"] = stdlib.JSONDecodeFunc | ||
47 | |||
48 | return hcl2Funcs | ||
49 | } | ||
50 | |||
51 | func hcl2InterpolationFuncShim(hilFunc ast.Function) function.Function { | ||
52 | spec := &function.Spec{} | ||
53 | |||
54 | for i, hilArgType := range hilFunc.ArgTypes { | ||
55 | spec.Params = append(spec.Params, function.Parameter{ | ||
56 | Type: hcl2shim.HCL2TypeForHILType(hilArgType), | ||
57 | Name: fmt.Sprintf("arg%d", i+1), // HIL args don't have names, so we'll fudge it | ||
58 | }) | ||
59 | } | ||
60 | |||
61 | if hilFunc.Variadic { | ||
62 | spec.VarParam = &function.Parameter{ | ||
63 | Type: hcl2shim.HCL2TypeForHILType(hilFunc.VariadicType), | ||
64 | Name: "varargs", // HIL args don't have names, so we'll fudge it | ||
65 | } | ||
66 | } | ||
67 | |||
68 | spec.Type = func(args []cty.Value) (cty.Type, error) { | ||
69 | return hcl2shim.HCL2TypeForHILType(hilFunc.ReturnType), nil | ||
70 | } | ||
71 | spec.Impl = func(args []cty.Value, retType cty.Type) (cty.Value, error) { | ||
72 | hilArgs := make([]interface{}, len(args)) | ||
73 | for i, arg := range args { | ||
74 | hilV := hcl2shim.HILVariableFromHCL2Value(arg) | ||
75 | |||
76 | // Although the cty function system does automatic type conversions | ||
77 | // to match the argument types, cty doesn't distinguish int and | ||
78 | // float and so we may need to adjust here to ensure that the | ||
79 | // wrapped function gets exactly the Go type it was expecting. | ||
80 | var wantType ast.Type | ||
81 | if i < len(hilFunc.ArgTypes) { | ||
82 | wantType = hilFunc.ArgTypes[i] | ||
83 | } else { | ||
84 | wantType = hilFunc.VariadicType | ||
85 | } | ||
86 | switch { | ||
87 | case hilV.Type == ast.TypeInt && wantType == ast.TypeFloat: | ||
88 | hilV.Type = wantType | ||
89 | hilV.Value = float64(hilV.Value.(int)) | ||
90 | case hilV.Type == ast.TypeFloat && wantType == ast.TypeInt: | ||
91 | hilV.Type = wantType | ||
92 | hilV.Value = int(hilV.Value.(float64)) | ||
93 | } | ||
94 | |||
95 | // HIL functions actually expect to have the outermost variable | ||
96 | // "peeled" but any nested values (in lists or maps) will | ||
97 | // still have their ast.Variable wrapping. | ||
98 | hilArgs[i] = hilV.Value | ||
99 | } | ||
100 | |||
101 | hilResult, err := hilFunc.Callback(hilArgs) | ||
102 | if err != nil { | ||
103 | return cty.DynamicVal, err | ||
104 | } | ||
105 | |||
106 | // Just as on the way in, we get back a partially-peeled ast.Variable | ||
107 | // which we need to re-wrap in order to convert it back into what | ||
108 | // we're calling a "config value". | ||
109 | rv := hcl2shim.HCL2ValueFromHILVariable(ast.Variable{ | ||
110 | Type: hilFunc.ReturnType, | ||
111 | Value: hilResult, | ||
112 | }) | ||
113 | |||
114 | return convert.Convert(rv, retType) // if result is unknown we'll force the correct type here | ||
115 | } | ||
116 | return function.New(spec) | ||
117 | } | ||
118 | |||
119 | func hcl2EvalWithUnknownVars(expr hcl2.Expression) (cty.Value, hcl2.Diagnostics) { | ||
120 | trs := expr.Variables() | ||
121 | vars := map[string]cty.Value{} | ||
122 | val := cty.DynamicVal | ||
123 | |||
124 | for _, tr := range trs { | ||
125 | name := tr.RootName() | ||
126 | vars[name] = val | ||
127 | } | ||
128 | |||
129 | ctx := &hcl2.EvalContext{ | ||
130 | Variables: vars, | ||
131 | Functions: hcl2InterpolationFuncs(), | ||
132 | } | ||
133 | return expr.Value(ctx) | ||
134 | } | ||