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

Commit

Permalink
tests pass again
Browse files Browse the repository at this point in the history
  • Loading branch information
Ernest Micklei authored and Ernest Micklei committed Jan 27, 2017
1 parent 0261da8 commit 26596d2
Show file tree
Hide file tree
Showing 16 changed files with 153 additions and 94 deletions.
20 changes: 10 additions & 10 deletions enum.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package proto3parser

import "fmt"
import (
"fmt"
"strconv"
)

type Enum struct {
Line int
Expand All @@ -11,7 +14,7 @@ type Enum struct {

type EnumField struct {
Name string
Constant string
Integer int
ValueOption *Option
}

Expand All @@ -24,15 +27,12 @@ func (f *EnumField) parse(p *Parser) error {
if tok != EQUALS {
return fmt.Errorf("found %q, expected =", lit)
}
ns := p.s.scanIntegerString()
if len(ns) != 0 {
f.Constant = ns
} else {
tok, lit = p.scanIgnoreWhitespace()
if tok != IDENT {
return fmt.Errorf("found %q, expected string", lit)
}
is := p.s.scanIntegerString()
i, err := strconv.Atoi(is)
if err != nil {
return fmt.Errorf("found %q, expected integer", is)
}
f.Integer = i
tok, lit = p.scanIgnoreWhitespace()
if tok == LEFTSQUARE {
o := new(Option)
Expand Down
6 changes: 6 additions & 0 deletions enum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,10 @@ enum EnumAllowingAlias {
if got, want := len(pr.Enums), 1; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
if got, want := len(pr.Enums[0].EnumFields), 3; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
if got, want := pr.Enums[0].EnumFields[0].Integer, 0; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}
3 changes: 2 additions & 1 deletion field.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ func parseField(f *Field, p *Parser) error {
//if tok == ONEOF {}
//if tok == ONEOFFIELD {}
case MESSAGE:
m, err := parseMessage(p)
m := new(Message)
err := m.parse(p)
if err != nil {
return err
}
Expand Down
6 changes: 5 additions & 1 deletion import.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ func (i *Import) parse(p *Parser) error {
}
i.Line = p.s.line
i.Kind = lit
name := p.s.scanUntil('\n')
tok, lit = p.scanIgnoreWhitespace()
if tok != QUOTE {
return fmt.Errorf("found %q, expected \"", lit)
}
name := p.s.scanUntil('"')
if len(name) == 0 {
return fmt.Errorf("unexpected end of quoted string")
}
Expand Down
13 changes: 6 additions & 7 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,15 @@ func (m Message) String() string {
return buf.String()
}

func parseMessage(p *Parser) (*Message, error) {
m := new(Message)
func (m *Message) parse(p *Parser) error {
tok, lit := p.scanIgnoreWhitespace()
if tok != IDENT {
return nil, fmt.Errorf("found %q, expected name", lit)
return fmt.Errorf("found %q, expected name", lit)
}
m.Name = lit
tok, lit = p.scanIgnoreWhitespace()
if tok != LEFTCURLY {
return nil, fmt.Errorf("found %q, expected {", lit)
return fmt.Errorf("found %q, expected {", lit)
}
for {
tok, lit = p.scanIgnoreWhitespace()
Expand All @@ -43,14 +42,14 @@ func parseMessage(p *Parser) (*Message, error) {
f := new(Field)
err := parseField(f, p)
if err != nil {
return nil, err
return err
}
m.Fields = append(m.Fields, f)
}
}
done:
if tok != RIGHTCURLY {
return nil, fmt.Errorf("found %q, expected }", lit)
return fmt.Errorf("found %q, expected }", lit)
}
return m, nil
return nil
}
9 changes: 4 additions & 5 deletions message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ package proto3parser
import (
"strings"
"testing"

"github.com/davecgh/go-spew/spew"
)

func TestMessage(t *testing.T) {
proto := `message AccountOut {}`
p := NewParser(strings.NewReader(proto))
p.scanIgnoreWhitespace() // consume first token
m, err := parseMessage(p)
m := new(Message)
err := m.parse(p)
if err != nil {
t.Fatal(err)
}
Expand All @@ -27,7 +26,8 @@ func TestMessageWithFields(t *testing.T) {
}`
p := NewParser(strings.NewReader(proto))
p.scanIgnoreWhitespace() // consume first token
m, err := parseMessage(p)
m := new(Message)
err := m.parse(p)
if err != nil {
t.Fatal(err)
}
Expand All @@ -37,5 +37,4 @@ func TestMessageWithFields(t *testing.T) {
if got, want := len(m.Fields), 2; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
spew.Dump(m)
}
7 changes: 5 additions & 2 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package proto3parser
import "fmt"

type Option struct {
Line int
Name string
String string
Boolean bool
Expand All @@ -12,6 +13,7 @@ func (o *Option) parse(p *Parser) error {
tok, lit := p.scanIgnoreWhitespace()
switch tok {
case IDENT:
o.Line = p.s.line
o.Name = lit
case LEFTPAREN:
tok, lit = p.scanIgnoreWhitespace()
Expand All @@ -32,8 +34,7 @@ func (o *Option) parse(p *Parser) error {
}
tok, lit = p.scanIgnoreWhitespace()
if tok == QUOTE {
p.unscan()
ident := p.s.scanUntil('\n')
ident := p.s.scanUntil('"')
if len(ident) == 0 {
return fmt.Errorf("unexpected end of quoted string") // TODO create constant for this
}
Expand All @@ -42,6 +43,8 @@ func (o *Option) parse(p *Parser) error {
}
if TRUE == tok || FALSE == tok {
o.Boolean = lit == "true"
} else {
return fmt.Errorf("found %q, expected true or false", lit)
}
return nil
}
9 changes: 9 additions & 0 deletions package.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package proto3parser

type Package struct {
Name string
}

func (a *Package) parse(p *Parser) error {
return nil
}
38 changes: 0 additions & 38 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,6 @@ import (
"testing"
)

func TestSyntax(t *testing.T) {
proto := `syntax = "proto3";`
p := NewParser(strings.NewReader(proto))
p.scanIgnoreWhitespace() // consume first token
syntax, err := parseSyntax(p)
if err != nil {
t.Fatal(err)
}
if got, want := syntax, "proto3"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}

func TestService(t *testing.T) {
proto := `service AccountService {}`
stmt, err := NewParser(strings.NewReader(proto)).Parse()
if err != nil {
t.Fatal(err)
}
if got, want := stmt.Services[0].Name, "AccountService"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}

func TestServiceWithRPCs(t *testing.T) {
proto := `service AccountService {
rpc CreateAccount (CreateAccount) returns (ServiceFault) {}
rpc GetAccount (Int64) returns (Account) {}
}`
stmt, err := NewParser(strings.NewReader(proto)).Parse()
if err != nil {
t.Fatal(err)
}
if got, want := len(stmt.Services[0].RPCalls), 2; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}

func TestCommentAroundSyntax(t *testing.T) {
proto := `
// comment1
Expand Down
34 changes: 7 additions & 27 deletions proto.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,14 @@
package proto3parser

import "fmt"

type Proto struct {
Syntax string
Syntax *Syntax
Imports []*Import
Enums []*Enum
Services []*Service
Messages []*Message
Comments []*Comment
}

// parseSyntax returns the syntax value. Parser has seen "syntax".
func parseSyntax(p *Parser) (string, error) {
if tok, lit := p.scanIgnoreWhitespace(); tok != EQUALS {
return "", fmt.Errorf("found %q, expected EQUALS", lit)
}
if tok, lit := p.scanIgnoreWhitespace(); tok != QUOTE {
return "", fmt.Errorf("found %q, expected QUOTE", lit)
}
tok, lit := p.scanIgnoreWhitespace()
if tok != IDENT {
return "", fmt.Errorf("found %q, expected string", lit)
}
if tok, lit := p.scanIgnoreWhitespace(); tok != QUOTE {
return "", fmt.Errorf("found %q, expected QUOTE", lit)
}
return lit, nil
}

// Comment holds a message and line number.
type Comment struct {
Line int
Expand All @@ -46,11 +26,11 @@ func parseProto(proto *Proto, p *Parser) error {
Message: lit,
})
case SYNTAX:
if syntax, err := parseSyntax(p); err != nil {
s := new(Syntax)
if err := s.parse(p); err != nil {
return err
} else {
proto.Syntax = syntax
}
proto.Syntax = s
case IMPORT:
im := new(Import)
if err := im.parse(p); err != nil {
Expand All @@ -70,11 +50,11 @@ func parseProto(proto *Proto, p *Parser) error {
proto.Services = append(proto.Services, service)
}
case MESSAGE:
if msg, err := parseMessage(p); err != nil {
msg := new(Message)
if err := msg.parse(p); err != nil {
return err
} else {
proto.Messages = append(proto.Messages, msg)
}
proto.Messages = append(proto.Messages, msg)
case EOF:
return nil
}
Expand Down
11 changes: 8 additions & 3 deletions scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func (s *scanner) scanWhitespace() (tok token, lit string) {
}

func (s *scanner) scanIntegerString() string {
s.scanWhitespace()
// Create a buffer and read the current character into it.
var buf bytes.Buffer
buf.WriteRune(s.read())
Expand Down Expand Up @@ -153,6 +154,10 @@ func (s *scanner) scanIdent() (tok token, lit string) {
return OPTION, buf.String()
case "ENUM":
return ENUM, buf.String()
case "TRUE":
return TRUE, buf.String()
case "FALSE":
return FALSE, buf.String()
}

// Otherwise return as a regular identifier.
Expand Down Expand Up @@ -187,8 +192,8 @@ func isDigit(ch rune) bool { return (ch >= '0' && ch <= '9') }
// eof represents a marker rune for the end of the reader.
var eof = rune(0)

// scanUntil returns the string up to (not including) the rune or EOF.
func (s *scanner) scanUntil(ch rune) string {
// scanUntil returns the string up to (not including) the terminator or EOF.
func (s *scanner) scanUntil(terminator rune) string {
// Create a buffer and read the current character into it.
var buf bytes.Buffer
buf.WriteRune(s.read())
Expand All @@ -197,7 +202,7 @@ func (s *scanner) scanUntil(ch rune) string {
for {
if ch := s.read(); ch == eof {
break
} else if ch == '\n' {
} else if ch == terminator {
break
} else {
buf.WriteRune(ch)
Expand Down
5 changes: 5 additions & 0 deletions service.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ func (s Service) String() string {
return buf.String()
}

// Accept dispatches the call to the visitor.
func (s *Service) Accept(v Visitor) {
v.VisitService(s)
}

func parseService(p *Parser) (*Service, error) {
s := new(Service)
tok, lit := p.scanIgnoreWhitespace()
Expand Down
31 changes: 31 additions & 0 deletions service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package proto3parser

import (
"strings"
"testing"
)

func TestService(t *testing.T) {
proto := `service AccountService {}`
stmt, err := NewParser(strings.NewReader(proto)).Parse()
if err != nil {
t.Fatal(err)
}
if got, want := stmt.Services[0].Name, "AccountService"; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}

func TestServiceWithRPCs(t *testing.T) {
proto := `service AccountService {
rpc CreateAccount (CreateAccount) returns (ServiceFault) {}
rpc GetAccount (Int64) returns (Account) {}
}`
stmt, err := NewParser(strings.NewReader(proto)).Parse()
if err != nil {
t.Fatal(err)
}
if got, want := len(stmt.Services[0].RPCalls), 2; got != want {
t.Errorf("got [%v] want [%v]", got, want)
}
}
Loading

0 comments on commit 26596d2

Please sign in to comment.