1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package proto
25
26 import (
27 "text/scanner"
28 )
29
30
31 type Field struct {
32 Position scanner.Position
33 Comment *Comment
34 Name string
35 Type string
36 Sequence int
37 Options []*Option
38 InlineComment *Comment
39 Parent Visitee
40 }
41
42
43 func (f *Field) inlineComment(c *Comment) {
44 f.InlineComment = c
45 }
46
47
48 type NormalField struct {
49 *Field
50 Repeated bool
51 Optional bool
52 Required bool
53 }
54
55 func newNormalField() *NormalField { return &NormalField{Field: new(Field)} }
56
57
58 func (f *NormalField) Accept(v Visitor) {
59 v.VisitNormalField(f)
60 }
61
62
63 func (f *NormalField) Doc() *Comment {
64 return f.Comment
65 }
66
67
68
69 func (f *NormalField) parse(p *Parser) error {
70 for {
71 pos, tok, lit := p.nextTypeName()
72 switch tok {
73 case tCOMMENT:
74 c := newComment(pos, lit)
75 if f.InlineComment == nil {
76 f.InlineComment = c
77 } else {
78 f.InlineComment.Merge(c)
79 }
80 case tREPEATED:
81 f.Repeated = true
82 return f.parse(p)
83 case tOPTIONAL:
84 f.Optional = true
85 return f.parse(p)
86 case tIDENT:
87 f.Type = lit
88 return parseFieldAfterType(f.Field, p, f)
89 default:
90 goto done
91 }
92 }
93 done:
94 return nil
95 }
96
97
98
99 func parseFieldAfterType(f *Field, p *Parser, parent Visitee) error {
100 expectedToken := tIDENT
101 expected := "field identifier"
102
103 for {
104 pos, tok, lit := p.next()
105 if tok == tCOMMENT {
106 c := newComment(pos, lit)
107 if f.InlineComment == nil {
108 f.InlineComment = c
109 } else {
110 f.InlineComment.Merge(c)
111 }
112 continue
113 }
114 if tok != expectedToken {
115
116 if expectedToken == tIDENT && isKeyword(tok) {
117
118 tok = tIDENT
119 } else {
120 return p.unexpected(lit, expected, f)
121 }
122 }
123
124 if tok == tIDENT {
125 f.Name = lit
126 expectedToken = tEQUALS
127 expected = "field ="
128 continue
129 }
130 if tok == tEQUALS {
131 expectedToken = tNUMBER
132 expected = "field sequence number"
133 continue
134 }
135 if tok == tNUMBER {
136
137 p.nextPut(pos, tok, lit)
138 i, err := p.nextInteger()
139 if err != nil {
140 return p.unexpected(lit, expected, f)
141 }
142 f.Sequence = i
143 break
144 }
145 }
146 consumeFieldComments(f, p)
147
148
149 pos, tok, lit := p.next()
150 if tLEFTSQUARE != tok {
151 p.nextPut(pos, tok, lit)
152 return nil
153 }
154
155 for {
156 o := new(Option)
157 o.Position = pos
158 o.IsEmbedded = true
159 o.parent(parent)
160 err := o.parse(p)
161 if err != nil {
162 return err
163 }
164 f.Options = append(f.Options, o)
165
166 pos, tok, lit = p.next()
167 if tRIGHTSQUARE == tok {
168 break
169 }
170 if tCOMMA != tok {
171 return p.unexpected(lit, "option ,", o)
172 }
173 }
174 return nil
175 }
176
177 func consumeFieldComments(f *Field, p *Parser) {
178 pos, tok, lit := p.next()
179 for tok == tCOMMENT {
180 c := newComment(pos, lit)
181 if f.InlineComment == nil {
182 f.InlineComment = c
183 } else {
184 f.InlineComment.Merge(c)
185 }
186 pos, tok, lit = p.next()
187 }
188
189 p.nextPut(pos, tok, lit)
190 }
191
192
193 type MapField struct {
194 *Field
195 KeyType string
196 }
197
198 func newMapField() *MapField { return &MapField{Field: new(Field)} }
199
200
201 func (f *MapField) Accept(v Visitor) {
202 v.VisitMapField(f)
203 }
204
205
206 func (f *MapField) Doc() *Comment {
207 return f.Comment
208 }
209
210
211
212
213
214
215 func (f *MapField) parse(p *Parser) error {
216 _, tok, lit := p.next()
217 if tLESS != tok {
218 return p.unexpected(lit, "map keyType <", f)
219 }
220 _, tok, lit = p.nextTypeName()
221 if tIDENT != tok {
222 return p.unexpected(lit, "map identifier", f)
223 }
224 f.KeyType = lit
225 _, tok, lit = p.next()
226 if tCOMMA != tok {
227 return p.unexpected(lit, "map type separator ,", f)
228 }
229 _, tok, lit = p.nextTypeName()
230 if tIDENT != tok {
231 return p.unexpected(lit, "map valueType identifier", f)
232 }
233 f.Type = lit
234 _, tok, lit = p.next()
235 if tGREATER != tok {
236 return p.unexpected(lit, "map valueType >", f)
237 }
238 return parseFieldAfterType(f.Field, p, f)
239 }
240
241 func (f *Field) parent(v Visitee) { f.Parent = v }
242
243 const optionNameDeprecated = "deprecated"
244
245
246 func (f *Field) IsDeprecated() bool {
247 for _, each := range f.Options {
248 if each.Name == optionNameDeprecated {
249 return each.Constant.Source == "true"
250 }
251 }
252 return false
253 }
254
View as plain text