3 // Type represents value types within the type system.
5 // This is a closed interface type, meaning that only the concrete
6 // implementations provided within this package are considered valid.
11 type typeImpl interface {
12 // isTypeImpl is a do-nothing method that exists only to express
13 // that a type is an implementation of typeImpl.
14 isTypeImpl() typeImplSigil
16 // Equals returns true if the other given Type exactly equals the
18 Equals(other Type) bool
20 // FriendlyName returns a human-friendly *English* name for the given
22 FriendlyName(mode friendlyTypeNameMode) string
24 // GoString implements the GoStringer interface from package fmt.
28 // Base implementation of Type to embed into concrete implementations
29 // to signal that they are implementations of Type.
30 type typeImplSigil struct{}
32 func (t typeImplSigil) isTypeImpl() typeImplSigil {
33 return typeImplSigil{}
36 // Equals returns true if the other given Type exactly equals the receiver
38 func (t Type) Equals(other Type) bool {
39 return t.typeImpl.Equals(other)
42 // FriendlyName returns a human-friendly *English* name for the given type.
43 func (t Type) FriendlyName() string {
44 return t.typeImpl.FriendlyName(friendlyTypeName)
47 // FriendlyNameForConstraint is similar to FriendlyName except that the
48 // result is specialized for describing type _constraints_ rather than types
49 // themselves. This is more appropriate when reporting that a particular value
50 // does not conform to an expected type constraint.
52 // In particular, this function uses the term "any type" to refer to
53 // cty.DynamicPseudoType, rather than "dynamic" as returned by FriendlyName.
54 func (t Type) FriendlyNameForConstraint() string {
55 return t.typeImpl.FriendlyName(friendlyTypeConstraintName)
58 // friendlyNameMode is an internal combination of the various FriendlyName*
59 // variants that just directly takes a mode, for easy passthrough for
60 // recursive name construction.
61 func (t Type) friendlyNameMode(mode friendlyTypeNameMode) string {
62 return t.typeImpl.FriendlyName(mode)
65 // GoString returns a string approximating how the receiver type would be
66 // expressed in Go source code.
67 func (t Type) GoString() string {
68 if t.typeImpl == nil {
72 return t.typeImpl.GoString()
75 // NilType is an invalid type used when a function is returning an error
76 // and has no useful type to return. It should not be used and any methods
77 // called on it will panic.
80 // HasDynamicTypes returns true either if the receiver is itself
81 // DynamicPseudoType or if it is a compound type whose descendent elements
82 // are DynamicPseudoType.
83 func (t Type) HasDynamicTypes() bool {
85 case t == DynamicPseudoType:
87 case t.IsPrimitiveType():
89 case t.IsCollectionType():
91 case t.IsObjectType():
92 attrTypes := t.AttributeTypes()
93 for _, at := range attrTypes {
94 if at.HasDynamicTypes() {
100 elemTypes := t.TupleElementTypes()
101 for _, et := range elemTypes {
102 if et.HasDynamicTypes() {
107 case t.IsCapsuleType():
110 // Should never happen, since above should be exhaustive
111 panic("HasDynamicTypes does not support the given type")
115 type friendlyTypeNameMode rune
118 friendlyTypeName friendlyTypeNameMode = 'N'
119 friendlyTypeConstraintName friendlyTypeNameMode = 'C'