Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue59 #67

Merged
merged 7 commits into from
Mar 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ func (l *Literal) parse(p *Parser) error {
type NamedLiteral struct {
*Literal
Name string
// PrintsColon is true when the Name must be printed with a colon suffix
PrintsColon bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this tested?

In previous versions, was the colon printed automatically/was it part of the Name? If so, this is backwards incompatible.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the colon was never part of the key. this change preserves that information such that any printer/formatter could use it to stay close to the original source.

}

// parseAggregate reads options written using aggregate syntax.
Expand Down Expand Up @@ -189,8 +191,22 @@ func parseAggregateConstants(p *Parser, container interface{}) (list []*NamedLit
err = p.unexpected(lit, "option aggregate key", container)
return
}
// workaround issue #59 TODO
if isString(lit) && len(list) > 0 {
// concatenate with previous constant
list[len(list)-1].Source += unQuote(lit)
continue
}
key := lit
printsColon := false
// expect colon, aggregate or plain literal
pos, tok, lit = p.next()
if tCOLON == tok {
// consume it
printsColon = true
pos, tok, lit = p.next()
}
// see if nested aggregate is started
if tLEFTCURLY == tok {
nested, fault := parseAggregateConstants(p, container)
if fault != nil {
Expand All @@ -206,15 +222,14 @@ func parseAggregateConstants(p *Parser, container interface{}) (list []*NamedLit
}
continue
}
if tCOLON != tok {
err = p.unexpected(lit, "option aggregate key colon :", container)
return
}
// no aggregate, put back token
p.nextPut(pos, tok, lit)
// now we see plain literal
l := new(Literal)
l.Position = pos
if err = l.parse(p); err != nil {
return
}
list = append(list, &NamedLiteral{Name: key, Literal: l})
list = append(list, &NamedLiteral{Name: key, Literal: l, PrintsColon: printsColon})
}
}
25 changes: 25 additions & 0 deletions option_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,3 +294,28 @@ func TestNestedAggregateConstants(t *testing.T) {
t.Errorf("got [%v] want [%v]", got, want)
}
}

// Issue #59
func TestMultiLineOptionAggregateValue(t *testing.T) {
src := `rpc ListTransferLogs(ListTransferLogsRequest)
returns (ListTransferLogsResponse) {
option (google.api.http) = {
get: "/v1/{parent=projects/*/locations/*/transferConfigs/*/runs/*}/"
"transferLogs"
};
}`
p := newParserOn(src)
rpc := new(RPC)
p.next()
err := rpc.parse(p)
if err != nil {
t.Error(err)
}
get := rpc.Options[0].AggregatedConstants[0]
if got, want := get.Name, "get"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
if got, want := get.Literal.Source, "/v1/{parent=projects/*/locations/*/transferConfigs/*/runs/*}/transferLogs"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}