-
Notifications
You must be signed in to change notification settings - Fork 77
/
field_type.go
171 lines (136 loc) · 4.74 KB
/
field_type.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package pgs
// FieldType describes the type of a Field.
type FieldType interface {
// Field returns the parent Field of this type. While two FieldTypes might be
// equivalent, each instance of a FieldType is tied to its Field.
Field() Field
// IsRepeated returns true if and only if the field is marked as "repeated".
// While map fields may be labeled as repeated, this method will not return
// true for them.
IsRepeated() bool
// IsMap returns true if the field is a map type.
IsMap() bool
// IsEnum returns true if the field is a singular enum value. Maps or
// repeated fields containing enums will still return false.
IsEnum() bool
// IsEmbed returns true if the field is a singular message value. Maps or
// repeated fields containing embeds will still return false.
IsEmbed() bool
// IsOptional returns true if the field is prefixed as optional.
IsOptional() bool
// IsRequired returns true if and only if the field is prefixed as required.
IsRequired() bool
// ProtoType returns the ProtoType value for this field.
ProtoType() ProtoType
// ProtoLabel returns the ProtoLabel value for this field.
ProtoLabel() ProtoLabel
// Imports includes all external proto files required by this field.
Imports() []File
// Enum returns the Enum associated with this FieldType. If IsEnum returns
// false, this value will be nil.
Enum() Enum
// Embed returns the embedded Message associated with this FieldType. If
// IsEmbed returns false, this value will be nil.
Embed() Message
// Element returns the FieldTypeElem representing the element component of
// the type.
//
// For repeated fields, the returned type describes the type being repeated (i.e.,
// the element type in the list implied by the repeated field).
//
// For maps, the returned type describes the type of values in the map.
//
// Nil will be returned if IsRepeated and IsMap both return false.
Element() FieldTypeElem
// Key returns the FieldTypeElem representing the key component of the type (i.e,
// the type of keys in a map).
//
// Nil will be returned if IsMap returns false.
Key() FieldTypeElem
setField(f Field)
toElem() FieldTypeElem
}
type scalarT struct{ fld Field }
func (s *scalarT) Field() Field { return s.fld }
func (s *scalarT) IsRepeated() bool { return false }
func (s *scalarT) IsMap() bool { return false }
func (s *scalarT) IsEnum() bool { return false }
func (s *scalarT) IsEmbed() bool { return false }
func (s *scalarT) ProtoType() ProtoType { return ProtoType(s.fld.Descriptor().GetType()) }
func (s *scalarT) ProtoLabel() ProtoLabel { return ProtoLabel(s.fld.Descriptor().GetLabel()) }
func (s *scalarT) Imports() []File { return nil }
func (s *scalarT) setField(f Field) { s.fld = f }
func (s *scalarT) Enum() Enum { return nil }
func (s *scalarT) Embed() Message { return nil }
func (s *scalarT) Element() FieldTypeElem { return nil }
func (s *scalarT) Key() FieldTypeElem { return nil }
func (s *scalarT) IsOptional() bool {
return !s.fld.Syntax().SupportsRequiredPrefix() || s.ProtoLabel() == Optional
}
func (s *scalarT) IsRequired() bool {
return s.fld.Syntax().SupportsRequiredPrefix() && s.ProtoLabel() == Required
}
func (s *scalarT) toElem() FieldTypeElem {
return &scalarE{
typ: s,
ptype: s.ProtoType(),
}
}
type enumT struct {
*scalarT
enum Enum
}
func (e *enumT) Enum() Enum { return e.enum }
func (e *enumT) IsEnum() bool { return true }
func (e *enumT) Imports() []File {
if f := e.enum.File(); f.Name() != e.fld.File().Name() {
return []File{f}
}
return nil
}
func (e *enumT) toElem() FieldTypeElem {
return &enumE{
scalarE: e.scalarT.toElem().(*scalarE),
enum: e.enum,
}
}
type embedT struct {
*scalarT
msg Message
}
func (e *embedT) Embed() Message { return e.msg }
func (e *embedT) IsEmbed() bool { return true }
func (e *embedT) Imports() []File {
if f := e.msg.File(); f.Name() != e.fld.File().Name() {
return []File{f}
}
return nil
}
func (e *embedT) toElem() FieldTypeElem {
return &embedE{
scalarE: e.scalarT.toElem().(*scalarE),
msg: e.msg,
}
}
type repT struct {
*scalarT
el FieldTypeElem
}
func (r *repT) IsRepeated() bool { return true }
func (r *repT) Element() FieldTypeElem { return r.el }
func (r *repT) Imports() []File { return r.el.Imports() }
func (r *repT) toElem() FieldTypeElem { panic("cannot convert repeated FieldType to FieldTypeElem") }
type mapT struct {
*repT
key FieldTypeElem
}
func (m *mapT) IsRepeated() bool { return false }
func (m *mapT) IsMap() bool { return true }
func (m *mapT) Key() FieldTypeElem { return m.key }
var (
_ FieldType = (*scalarT)(nil)
_ FieldType = (*enumT)(nil)
_ FieldType = (*embedT)(nil)
_ FieldType = (*repT)(nil)
_ FieldType = (*mapT)(nil)
)