Skip to content
This repository has been archived by the owner on Jan 5, 2019. It is now read-only.

Commit

Permalink
work on issue emicklei#3
Browse files Browse the repository at this point in the history
  • Loading branch information
Ernest Micklei authored and Ernest Micklei committed Mar 9, 2017
1 parent 94eb556 commit a156327
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 36 deletions.
5 changes: 4 additions & 1 deletion cmd/protofmt/unformatted.proto
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,7 @@ enum enum {
}
message message {
sometype message = 1; // message
}
}

// custom option
extend google.protobuf.MessageOptions { optional string my_option = 51234; }
8 changes: 4 additions & 4 deletions field_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Copyright (c) 2017 Ernest Micklei
//
//
// MIT License
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand Down
8 changes: 4 additions & 4 deletions message_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Copyright (c) 2017 Ernest Micklei
//
//
// MIT License
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand Down
49 changes: 41 additions & 8 deletions option.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Copyright (c) 2017 Ernest Micklei
//
//
// MIT License
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand All @@ -27,10 +27,11 @@ import "fmt"

// Option is a protoc compiler option
type Option struct {
Name string
Constant Literal
IsEmbedded bool
Comment *Comment
Name string
Constant Literal
IsEmbedded bool
Comment *Comment
AggregatedConstants map[string]*Literal
}

// inlineComment is part of commentInliner.
Expand Down Expand Up @@ -111,6 +112,12 @@ func (o *Option) parse(p *Parser) error {
if tEQUALS != tok {
return p.unexpected(lit, "option constant =", o)
}
tok, lit = p.scanIgnoreWhitespace()
if tLEFTCURLY == tok {
return o.parseAggregate(p)
}
p.s.unread(rune(lit[0])) // danger robinson
// non aggregate
l := new(Literal)
if err := l.parse(p); err != nil {
return err
Expand Down Expand Up @@ -138,3 +145,29 @@ func (l *Literal) parse(p *Parser) error {
l.Source, l.IsString = p.s.scanLiteral()
return nil
}

// parseAggregate reads options written using aggregate syntax
func (o *Option) parseAggregate(p *Parser) error {
o.AggregatedConstants = map[string]*Literal{}
for {
tok, lit := p.scanIgnoreWhitespace()
if tRIGHTCURLY == tok {
break
}
if tIDENT != tok {
return p.unexpected(lit, "option aggregate key", o)
}
tok, lit = p.scanIgnoreWhitespace()
if tCOLON != tok {
return p.unexpected(lit, "option aggregate key colon :", o)
}
key := lit
tok, lit = p.scanIgnoreWhitespace()
l := new(Literal)
if err := l.parse(p); err != nil {
return err
}
o.AggregatedConstants[key] = l
}
return nil
}
32 changes: 26 additions & 6 deletions option_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Copyright (c) 2017 Ernest Micklei
//
//
// MIT License
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand All @@ -25,7 +25,7 @@ package proto

import "testing"

func TestOption(t *testing.T) {
func TestOptionCases(t *testing.T) {
for i, each := range []struct {
proto string
name string
Expand All @@ -46,11 +46,16 @@ func TestOption(t *testing.T) {
"Float",
"",
"-3.14E1",
}, {
`option (foo_options) = { opt1: 123 opt2: "baz" };`,
"foo_options",
"",
"",
}} {
p := newParserOn(each.proto)
pr, err := p.Parse()
if err != nil {
t.Fatal(err)
t.Fatal("testcase failed:", i, err)
}
if got, want := len(pr.Elements), 1; got != want {
t.Fatalf("[%d] got [%v] want [%v]", i, got, want)
Expand All @@ -74,3 +79,18 @@ func TestOption(t *testing.T) {
}
}
}

func TestLiteralString(t *testing.T) {
proto := `"string"`
p := newParserOn(proto)
l := new(Literal)
if err := l.parse(p); err != nil {
t.Fatal(err)
}
if got, want := l.IsString, true; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
if got, want := l.Source, "string"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}
10 changes: 5 additions & 5 deletions parser.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Copyright (c) 2017 Ernest Micklei
//
//
// MIT License
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand Down Expand Up @@ -92,5 +92,5 @@ func (p *Parser) unexpected(found, expected string, obj interface{}) error {
_, file, line, _ := runtime.Caller(1)
debug = fmt.Sprintf(" at %s:%d (with %#v)", file, line, obj)
}
return fmt.Errorf("found %q on line %d, expected %s%s", found, p.s.line, expected, debug)
return fmt.Errorf("found %q on line %d, expected [%s]%s", found, p.s.line, expected, debug)
}
2 changes: 2 additions & 0 deletions scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ func (s *scanner) scan() (tok token, lit string) {
return tEOF, ""
case ';':
return tSEMICOLON, string(ch)
case ':':
return tCOLON, string(ch)
case '=':
return tEQUALS, string(ch)
case '"':
Expand Down
31 changes: 27 additions & 4 deletions service_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Copyright (c) 2017 Ernest Micklei
//
//
// MIT License
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand Down Expand Up @@ -48,3 +48,26 @@ func TestService(t *testing.T) {
t.Errorf("got [%v] want [%v]", got, want)
}
}

func TestRPCWithOptionAggregateSyntax(t *testing.T) {
proto := `service AccountService {
rpc CreateAccount (CreateAccount) returns (ServiceFault){
option (test_ident) = {
test: "test"
test2:"test2"
};
}
}`
pr, err := newParserOn(proto).Parse()
if err != nil {
t.Fatal(err)
}
srv := collect(pr).Services()[0]
if got, want := len(srv.Elements), 3; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
rpc1 := srv.Elements[1].(*RPC)
if got, want := len(rpc1.Options), 1; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}
9 changes: 5 additions & 4 deletions token.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// Copyright (c) 2017 Ernest Micklei
//
//
// MIT License
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Expand All @@ -37,6 +37,7 @@ const (

// Misc characters
tSEMICOLON // ;
tCOLON // :
tEQUALS // =
tQUOTE // "
tSINGLEQUOTE // '
Expand Down

0 comments on commit a156327

Please sign in to comment.