type.go 5.67 KB
Newer Older
Eric Myhre's avatar
Eric Myhre committed
1
package schema
Eric Myhre's avatar
Eric Myhre committed
2

3
import (
4
	ipld "github.com/ipld/go-ipld-prime"
5 6
)

Eric Myhre's avatar
Eric Myhre committed
7
type TypeName string // = ast.TypeName
8

9 10
func (tn TypeName) String() string { return string(tn) }

11 12 13 14 15 16 17 18 19 20 21 22 23 24
// typesystem.Type is an union interface; each of the `Type*` concrete types
// in this package are one of its members.
//
// Specifically,
//
// 	TypeBool
// 	TypeString
// 	TypeBytes
// 	TypeInt
// 	TypeFloat
// 	TypeMap
// 	TypeList
// 	TypeLink
// 	TypeUnion
Eric Myhre's avatar
Eric Myhre committed
25
// 	TypeStruct
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
// 	TypeEnum
//
// are all of the kinds of Type.
//
// This is a closed union; you can switch upon the above members without
// including a default case.  The membership is closed by the unexported
// '_Type' method; you may use the BurntSushi/go-sumtype tool to check
// your switches for completeness.
//
// Many interesting properties of each Type are only defined for that specific
// type, so it's typical to use a type switch to handle each type of Type.
// (Your humble author is truly sorry for the word-mash that results from
// attempting to describe the types that describe the typesystem.Type.)
//
// For example, to inspect the kind of fields in a struct: you might
// cast a `Type` interface into `TypeStruct`, and then the `Fields()` on
// that `TypeStruct` can be inspected.  (`Fields()` isn't defined for any
// other kind of Type.)
type Type interface {
	// Unexported marker method to force the union closed.
	_Type()
47

48
	// Returns a pointer to the TypeSystem this Type is a member of.
Eric Myhre's avatar
Eric Myhre committed
49
	TypeSystem() *TypeSystem
50

51 52 53 54 55
	// Returns the string name of the Type.  This name is unique within the
	// universe this type is a member of, *unless* this type is Anonymous,
	// in which case a string describing the type will still be returned, but
	// that string will not be required to be unique.
	Name() TypeName
Eric Myhre's avatar
Eric Myhre committed
56

57
	// Returns the Kind of this Type.
58
	//
59 60 61 62 63
	// The returned value is a 1:1 association with which of the concrete
	// "schema.Type*" structs this interface can be cast to.
	//
	// Note that a schema.Kind is a different enum than ipld.ReprKind;
	// and furthermore, there's no strict relationship between them.
64
	// schema.TypedNode values can be described by *two* distinct ReprKinds:
65 66 67 68 69
	// one which describes how the Node itself will act,
	// and another which describes how the Node presents for serialization.
	// For some combinations of Type and representation strategy, one or both
	// of the ReprKinds can be determined statically; but not always:
	// it can sometimes be necessary to inspect the value quite concretely
70
	// (e.g., `schema.TypedNode{}.Representation().ReprKind()`) in order to find
71 72 73 74
	// out exactly how a node will be serialized!  This is because some types
	// can vary in representation kind based on their value (specifically,
	// kinded-representation unions have this property).
	Kind() Kind
Eric Myhre's avatar
Eric Myhre committed
75 76
}

77 78 79 80 81 82 83 84 85 86
var (
	_ Type = TypeBool{}
	_ Type = TypeString{}
	_ Type = TypeBytes{}
	_ Type = TypeInt{}
	_ Type = TypeFloat{}
	_ Type = TypeMap{}
	_ Type = TypeList{}
	_ Type = TypeLink{}
	_ Type = TypeUnion{}
Eric Myhre's avatar
Eric Myhre committed
87
	_ Type = TypeStruct{}
88 89 90
	_ Type = TypeEnum{}
)

91 92
type anyType struct {
	name     TypeName
Eric Myhre's avatar
Eric Myhre committed
93
	universe *TypeSystem
94 95
}

Eric Myhre's avatar
Eric Myhre committed
96
type TypeBool struct {
97
	anyType
Eric Myhre's avatar
Eric Myhre committed
98
}
99

Eric Myhre's avatar
Eric Myhre committed
100
type TypeString struct {
101
	anyType
Eric Myhre's avatar
Eric Myhre committed
102
}
103

Eric Myhre's avatar
Eric Myhre committed
104
type TypeBytes struct {
105
	anyType
Eric Myhre's avatar
Eric Myhre committed
106
}
107

Eric Myhre's avatar
Eric Myhre committed
108
type TypeInt struct {
109
	anyType
Eric Myhre's avatar
Eric Myhre committed
110
}
111

Eric Myhre's avatar
Eric Myhre committed
112
type TypeFloat struct {
113
	anyType
Eric Myhre's avatar
Eric Myhre committed
114
}
115

Eric Myhre's avatar
Eric Myhre committed
116
type TypeMap struct {
117 118 119 120 121
	anyType
	anonymous     bool
	keyType       Type // must be ReprKind==string (e.g. Type==String|Enum).
	valueType     Type
	valueNullable bool
Eric Myhre's avatar
Eric Myhre committed
122
}
123

Eric Myhre's avatar
Eric Myhre committed
124
type TypeList struct {
125 126 127 128
	anyType
	anonymous     bool
	valueType     Type
	valueNullable bool
Eric Myhre's avatar
Eric Myhre committed
129
}
130

Eric Myhre's avatar
Eric Myhre committed
131
type TypeLink struct {
132
	anyType
133 134
	referencedType    Type
	hasReferencedType bool
Eric Myhre's avatar
Eric Myhre committed
135 136 137 138
	// ...?
}

type TypeUnion struct {
139 140 141
	anyType
	style        UnionStyle
	valuesKinded map[ipld.ReprKind]Type // for Style==Kinded
142
	values       map[string]Type        // for Style!=Kinded (note, key is freetext, not necessarily TypeName of the value)
143 144
	typeHintKey  string                 // for Style==Envelope|Inline
	contentKey   string                 // for Style==Envelope
Eric Myhre's avatar
Eric Myhre committed
145
}
146

Eric Myhre's avatar
Eric Myhre committed
147 148 149 150 151 152 153 154 155
type UnionStyle struct{ x string }

var (
	UnionStyle_Kinded   = UnionStyle{"kinded"}
	UnionStyle_Keyed    = UnionStyle{"keyed"}
	UnionStyle_Envelope = UnionStyle{"envelope"}
	UnionStyle_Inline   = UnionStyle{"inline"}
)

Eric Myhre's avatar
Eric Myhre committed
156
type TypeStruct struct {
157
	anyType
158 159 160 161
	// n.b. `Fields` is an (order-preserving!) map in the schema-schema;
	//  but it's a list here, with the keys denormalized into the value,
	//   because that's typically how we use it.
	fields         []StructField
162
	fieldsMap      map[string]StructField // same content, indexed for lookup.
163
	representation StructRepresentation
Eric Myhre's avatar
Eric Myhre committed
164
}
Eric Myhre's avatar
Eric Myhre committed
165
type StructField struct {
166
	parent   *TypeStruct
167 168 169 170
	name     string
	typ      Type
	optional bool
	nullable bool
Eric Myhre's avatar
Eric Myhre committed
171 172
}

173 174 175 176 177 178 179 180 181
type StructRepresentation interface{ _StructRepresentation() }

func (StructRepresentation_Map) _StructRepresentation()         {}
func (StructRepresentation_Tuple) _StructRepresentation()       {}
func (StructRepresentation_StringPairs) _StructRepresentation() {}
func (StructRepresentation_StringJoin) _StructRepresentation()  {}

type StructRepresentation_Map struct {
	renames   map[string]string
182
	implicits map[string]ImplicitValue
183 184 185 186 187
}
type StructRepresentation_Tuple struct{}
type StructRepresentation_StringPairs struct{ sep1, sep2 string }
type StructRepresentation_StringJoin struct{ sep string }

Eric Myhre's avatar
Eric Myhre committed
188
type TypeEnum struct {
189 190
	anyType
	members []string
Eric Myhre's avatar
Eric Myhre committed
191
}
192 193 194 195 196 197 198 199 200 201 202

// ImplicitValue is an sum type holding values that are implicits.
// It's not an 'Any' value because it can't be recursive
// (or to be slightly more specific, it can be one of the recursive kinds,
// but if so, only its empty value is valid here).
type ImplicitValue interface{ _ImplicitValue() }

type ImplicitValue_EmptyList struct{}
type ImplicitValue_EmptyMap struct{}
type ImplicitValue_String struct{ x string }
type ImplicitValue_Int struct{ x int }