Skip to content

Commit

Permalink
Tolerate missing '=' value in compact options (bufbuild#219)
Browse files Browse the repository at this point in the history
While still producing an error, see:
bufbuild#200
  • Loading branch information
Alfus authored and kralicky committed Feb 7, 2024
1 parent 93dcc4a commit 7a7c2a1
Show file tree
Hide file tree
Showing 4 changed files with 269 additions and 211 deletions.
15 changes: 10 additions & 5 deletions ast/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,18 @@ func NewCompactOptionNode(name *OptionNameNode, equals *RuneNode, val ValueNode)
if name == nil {
panic("name is nil")
}
if equals == nil {
panic("equals is nil")
if equals == nil && val != nil {
panic("equals is nil but val is not")
}
if val == nil {
panic("val is nil")
if val == nil && equals != nil {
panic("val is nil but equals is not")
}
var children []Node
if equals == nil && val == nil {
children = []Node{name}
} else {
children = []Node{name, equals, val}
}
children := []Node{name, equals, val}
return &OptionNode{
compositeNode: compositeNode{
children: children,
Expand Down
41 changes: 41 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,47 @@ func TestLenientParse_EmptyCompactOptions(t *testing.T) {
}
}

func TestLenientParse_EmptyCompactValue(t *testing.T) {
t.Parallel()
inputs := map[string]struct {
Error string
NoError string
}{
"field-options": {
Error: `syntax = "proto2";
message Foo {
optional int32 bar = 1 [deprecated=true, default];
}`,
NoError: `syntax = "proto3";
message Foo {
optional int32 bar = 1 [deprecated=true, default=1];
}`,
},
"enum-options": {
Error: `syntax = "proto3";
enum Foo {
FOO = 0 [deprecated];
}`,
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 option must have a value")
})
}
}

func TestSimpleParse(t *testing.T) {
t.Parallel()
protos := map[string]Result{}
Expand Down
5 changes: 5 additions & 0 deletions parser/proto.y
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,11 @@ compactOptionDecls : compactOption {
compactOption: optionName '=' optionValue {
optName := ast.NewOptionNameNode($1.refs, $1.dots)
$$ = ast.NewCompactOptionNode(optName, $2, $3)
} |
optionName {
optName := ast.NewOptionNameNode($1.refs, $1.dots)
protolex.(*protoLex).Error("compact option must have a value")
$$ = ast.NewCompactOptionNode(optName, nil, nil)
}

groupDecl : fieldCardinality _GROUP identifier '=' _INT_LIT '{' messageBody '}' {
Expand Down
Loading

0 comments on commit 7a7c2a1

Please sign in to comment.