]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/hcl2/ext/typeexpr/public.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / hcl2 / ext / typeexpr / public.go
1 package typeexpr
2
3 import (
4 "bytes"
5 "fmt"
6 "sort"
7
8 "github.com/hashicorp/hcl2/hcl/hclsyntax"
9
10 "github.com/hashicorp/hcl2/hcl"
11 "github.com/zclconf/go-cty/cty"
12 )
13
14 // Type attempts to process the given expression as a type expression and, if
15 // successful, returns the resulting type. If unsuccessful, error diagnostics
16 // are returned.
17 func Type(expr hcl.Expression) (cty.Type, hcl.Diagnostics) {
18 return getType(expr, false)
19 }
20
21 // TypeConstraint attempts to parse the given expression as a type constraint
22 // and, if successful, returns the resulting type. If unsuccessful, error
23 // diagnostics are returned.
24 //
25 // A type constraint has the same structure as a type, but it additionally
26 // allows the keyword "any" to represent cty.DynamicPseudoType, which is often
27 // used as a wildcard in type checking and type conversion operations.
28 func TypeConstraint(expr hcl.Expression) (cty.Type, hcl.Diagnostics) {
29 return getType(expr, true)
30 }
31
32 // TypeString returns a string rendering of the given type as it would be
33 // expected to appear in the HCL native syntax.
34 //
35 // This is primarily intended for showing types to the user in an application
36 // that uses typexpr, where the user can be assumed to be familiar with the
37 // type expression syntax. In applications that do not use typeexpr these
38 // results may be confusing to the user and so type.FriendlyName may be
39 // preferable, even though it's less precise.
40 //
41 // TypeString produces reasonable results only for types like what would be
42 // produced by the Type and TypeConstraint functions. In particular, it cannot
43 // support capsule types.
44 func TypeString(ty cty.Type) string {
45 // Easy cases first
46 switch ty {
47 case cty.String:
48 return "string"
49 case cty.Bool:
50 return "bool"
51 case cty.Number:
52 return "number"
53 case cty.DynamicPseudoType:
54 return "any"
55 }
56
57 if ty.IsCapsuleType() {
58 panic("TypeString does not support capsule types")
59 }
60
61 if ty.IsCollectionType() {
62 ety := ty.ElementType()
63 etyString := TypeString(ety)
64 switch {
65 case ty.IsListType():
66 return fmt.Sprintf("list(%s)", etyString)
67 case ty.IsSetType():
68 return fmt.Sprintf("set(%s)", etyString)
69 case ty.IsMapType():
70 return fmt.Sprintf("map(%s)", etyString)
71 default:
72 // Should never happen because the above is exhaustive
73 panic("unsupported collection type")
74 }
75 }
76
77 if ty.IsObjectType() {
78 var buf bytes.Buffer
79 buf.WriteString("object({")
80 atys := ty.AttributeTypes()
81 names := make([]string, 0, len(atys))
82 for name := range atys {
83 names = append(names, name)
84 }
85 sort.Strings(names)
86 first := true
87 for _, name := range names {
88 aty := atys[name]
89 if !first {
90 buf.WriteByte(',')
91 }
92 if !hclsyntax.ValidIdentifier(name) {
93 // Should never happen for any type produced by this package,
94 // but we'll do something reasonable here just so we don't
95 // produce garbage if someone gives us a hand-assembled object
96 // type that has weird attribute names.
97 // Using Go-style quoting here isn't perfect, since it doesn't
98 // exactly match HCL syntax, but it's fine for an edge-case.
99 buf.WriteString(fmt.Sprintf("%q", name))
100 } else {
101 buf.WriteString(name)
102 }
103 buf.WriteByte('=')
104 buf.WriteString(TypeString(aty))
105 first = false
106 }
107 buf.WriteString("})")
108 return buf.String()
109 }
110
111 if ty.IsTupleType() {
112 var buf bytes.Buffer
113 buf.WriteString("tuple([")
114 etys := ty.TupleElementTypes()
115 first := true
116 for _, ety := range etys {
117 if !first {
118 buf.WriteByte(',')
119 }
120 buf.WriteString(TypeString(ety))
121 first = false
122 }
123 buf.WriteString("])")
124 return buf.String()
125 }
126
127 // Should never happen because we covered all cases above.
128 panic(fmt.Errorf("unsupported type %#v", ty))
129 }