Skip to content

Commit

Permalink
Tolerate empty compact options (#211)
Browse files Browse the repository at this point in the history
While still producing an error. See
#200
  • Loading branch information
Alfus authored Dec 4, 2023
1 parent fc56311 commit ec8c634
Show file tree
Hide file tree
Showing 4 changed files with 458 additions and 401 deletions.
6 changes: 3 additions & 3 deletions ast/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,10 @@ func NewCompactOptionsNode(openBracket *RuneNode, opts []*OptionNode, commas []*
if closeBracket == nil {
panic("closeBracket is nil")
}
if len(opts) == 0 {
panic("must have at least one part")
if len(opts) == 0 && len(commas) != 0 {
panic("opts is empty but commas is not")
}
if len(commas) != len(opts)-1 {
if len(opts) > 0 && len(commas) != len(opts)-1 {
panic(fmt.Sprintf("%d opts requires %d commas, not %d", len(opts), len(opts)-1, len(commas)))
}
children := make([]Node, 0, len(opts)*2+1)
Expand Down
41 changes: 41 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,47 @@ func TestLenientParse_SemicolonLess(t *testing.T) {
}
}

func TestLenientParse_EmptyCompactOptions(t *testing.T) {
t.Parallel()
inputs := map[string]struct {
Error string
NoError string
}{
"field-options": {
Error: `syntax = "proto3";
message Foo {
int32 bar = 1 [];
}`,
NoError: `syntax = "proto3";
message Foo {
int32 bar = 1 [default=1];
}`,
},
"enum-options": {
Error: `syntax = "proto3";
enum Foo {
FOO = 0 [];
}`,
NoError: `syntax = "proto3";
enum Foo {
FOO = 0 [deprecated=true];
}`,
},
}
for name, input := range inputs {
name, input := name, input
t.Run(name, func(t *testing.T) {
t.Parallel()
errHandler := reporter.NewHandler(nil)
protoName := fmt.Sprintf("%s.proto", name)
_, err := Parse(protoName, strings.NewReader(input.NoError), errHandler)
require.NoError(t, err)
_, err = Parse(protoName, strings.NewReader(input.Error), errHandler)
require.ErrorContains(t, err, "compact options must have at least one option")
})
}
}

func TestSimpleParse(t *testing.T) {
t.Parallel()
protos := map[string]Result{}
Expand Down
4 changes: 4 additions & 0 deletions parser/proto.y
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,10 @@ fieldCardinality : _REQUIRED
compactOptions: '[' compactOptionDecls ']' {
$$ = ast.NewCompactOptionsNode($1, $2.options, $2.commas, $3)
}
| '[' ']' {
protolex.(*protoLex).Error("compact options must have at least one option")
$$ = ast.NewCompactOptionsNode($1, nil, nil, $2)
}

compactOptionDecls : compactOption {
$$ = &compactOptionSlices{options: []*ast.OptionNode{$1}}
Expand Down
Loading

0 comments on commit ec8c634

Please sign in to comment.