Skip to content

Commit 582b687

Browse files
authored
Merge pull request #40 from yoheimuta/support-option
feat: Support oneof options
2 parents 549488d + 21f2c7e commit 582b687

File tree

3 files changed

+123
-7
lines changed

3 files changed

+123
-7
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ test/lint:
1919
# checks the error the compiler can't find.
2020
go vet ./...
2121
# checks shadowed variables.
22-
go vet -shadow ./...
22+
go vet -vettool=$(which shadow) ./...
2323
# checks not to ignore the error.
2424
errcheck ./...
2525
# checks unused global variables and constants.

parser/oneof.go

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ type Oneof struct {
4444
OneofFields []*OneofField
4545
OneofName string
4646

47+
Options []*Option
48+
4749
// Comments are the optional ones placed at the beginning.
4850
Comments []*Comment
4951
// InlineComment is the optional one placed at the ending.
@@ -68,6 +70,9 @@ func (o *Oneof) Accept(v Visitor) {
6870
for _, field := range o.OneofFields {
6971
field.Accept(v)
7072
}
73+
for _, option := range o.Options {
74+
option.Accept(v)
75+
}
7176
for _, comment := range o.Comments {
7277
comment.Accept(v)
7378
}
@@ -101,6 +106,7 @@ func (p *Parser) ParseOneof() (*Oneof, error) {
101106
inlineLeftCurly := p.parseInlineComment()
102107

103108
var oneofFields []*OneofField
109+
var options []*Option
104110
for {
105111
comments := p.ParseComments()
106112

@@ -109,13 +115,27 @@ func (p *Parser) ParseOneof() (*Oneof, error) {
109115
continue
110116
}
111117

112-
oneofField, err := p.parseOneofField()
113-
if err != nil {
114-
return nil, err
118+
p.lex.NextKeyword()
119+
token := p.lex.Token
120+
p.lex.UnNext()
121+
if p.permissive && token == scanner.TOPTION {
122+
// accept an option. See https://github.com/yoheimuta/go-protoparser/issues/39.
123+
option, err := p.ParseOption()
124+
if err != nil {
125+
return nil, err
126+
}
127+
option.Comments = comments
128+
p.MaybeScanInlineComment(option)
129+
options = append(options, option)
130+
} else {
131+
oneofField, err := p.parseOneofField()
132+
if err != nil {
133+
return nil, err
134+
}
135+
oneofField.Comments = comments
136+
p.MaybeScanInlineComment(oneofField)
137+
oneofFields = append(oneofFields, oneofField)
115138
}
116-
oneofField.Comments = comments
117-
p.MaybeScanInlineComment(oneofField)
118-
oneofFields = append(oneofFields, oneofField)
119139

120140
p.lex.Next()
121141
if p.lex.Token == scanner.TRIGHTCURLY {
@@ -137,6 +157,7 @@ func (p *Parser) ParseOneof() (*Oneof, error) {
137157
return &Oneof{
138158
OneofFields: oneofFields,
139159
OneofName: oneofName,
160+
Options: options,
140161
InlineCommentBehindLeftCurly: inlineLeftCurly,
141162
Meta: meta.NewMetaWithLastPos(startPos, lastPos),
142163
}, nil

parser/oneof_test.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,101 @@ func TestParser_ParseOneof(t *testing.T) {
367367
},
368368
},
369369
},
370+
{
371+
name: "accept options. See https://github.com/yoheimuta/go-protoparser/issues/39",
372+
input: `oneof something {
373+
option (validator.oneof) = {required: true};
374+
uint32 three_int = 5 [(validator.field) = {int_gt: 20}];
375+
uint32 four_int = 6 [(validator.field) = {int_gt: 100}];
376+
string five_regex = 7 [(validator.field) = {regex: "^[a-z]{2,5}$"}];
377+
}
378+
`,
379+
permissive: true,
380+
wantOneof: &parser.Oneof{
381+
OneofFields: []*parser.OneofField{
382+
{
383+
Type: "uint32",
384+
FieldName: "three_int",
385+
FieldNumber: "5",
386+
FieldOptions: []*parser.FieldOption{
387+
{
388+
OptionName: "(validator.field)",
389+
Constant: "{int_gt:20}",
390+
},
391+
},
392+
Meta: meta.Meta{
393+
Pos: meta.Position{
394+
Offset: 67,
395+
Line: 3,
396+
Column: 3,
397+
},
398+
},
399+
},
400+
{
401+
Type: "uint32",
402+
FieldName: "four_int",
403+
FieldNumber: "6",
404+
FieldOptions: []*parser.FieldOption{
405+
{
406+
OptionName: "(validator.field)",
407+
Constant: "{int_gt:100}",
408+
},
409+
},
410+
Meta: meta.Meta{
411+
Pos: meta.Position{
412+
Offset: 126,
413+
Line: 4,
414+
Column: 3,
415+
},
416+
},
417+
},
418+
{
419+
Type: "string",
420+
FieldName: "five_regex",
421+
FieldNumber: "7",
422+
FieldOptions: []*parser.FieldOption{
423+
{
424+
OptionName: "(validator.field)",
425+
Constant: "{regex:\"^[a-z]{2,5}$\"}",
426+
},
427+
},
428+
Meta: meta.Meta{
429+
Pos: meta.Position{
430+
Offset: 185,
431+
Line: 5,
432+
Column: 3,
433+
},
434+
},
435+
},
436+
},
437+
Options: []*parser.Option{
438+
{
439+
OptionName: "(validator.oneof)",
440+
Constant: "{required:true}",
441+
Meta: meta.Meta{
442+
Pos: meta.Position{
443+
Offset: 20,
444+
Line: 2,
445+
Column: 3,
446+
},
447+
},
448+
},
449+
},
450+
OneofName: "something",
451+
Meta: meta.Meta{
452+
Pos: meta.Position{
453+
Offset: 0,
454+
Line: 1,
455+
Column: 1,
456+
},
457+
LastPos: meta.Position{
458+
Offset: 254,
459+
Line: 6,
460+
Column: 1,
461+
},
462+
},
463+
},
464+
},
370465
}
371466

372467
for _, test := range tests {

0 commit comments

Comments
 (0)