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

Commit

Permalink
refactoring, better line count, begin with visitor, travis
Browse files Browse the repository at this point in the history
  • Loading branch information
Ernest Micklei authored and Ernest Micklei committed Jan 28, 2017
1 parent 1c16ca7 commit 768352c
Show file tree
Hide file tree
Showing 19 changed files with 205 additions and 111 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
language: go

go:
- 1.x
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# proto3

Package for parsing Google Protocol Buffers [.proto files version 3] (https://developers.google.com/protocol-buffers/docs/reference/proto3-spec)
[![Build Status](https://travis-ci.org/emicklei/proto3.png)](https://travis-ci.org/emicklei/proto3)

Package in Go for parsing Google Protocol Buffers [.proto files version 3] (https://developers.google.com/protocol-buffers/docs/reference/proto3-spec)

### install

go get -u -v github.com/emicklei/proto

(c) 2017, ernestmicklei.com. MIT License. Contributions welcome.
5 changes: 0 additions & 5 deletions cmd/main.go

This file was deleted.

56 changes: 56 additions & 0 deletions cmd/proto3fmt/example1.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
syntax = "proto3";

import "google/protobuf/any.proto";
import "testdata/test.proto";

package proto3_proto;

message Message {
enum Humour {
UNKNOWN = 0;
PUNS = 1;
SLAPSTICK = 2;
BILL_BAILEY = 3;
}

string name = 1;
Humour hilarity = 2;
uint32 height_in_cm = 3;
bytes data = 4;
int64 result_count = 7;
bool true_scotsman = 8;
float score = 9;

repeated uint64 key = 5;
repeated int32 short_key = 19;
Nested nested = 6;
repeated Humour r_funny = 16;

map<string, Nested> terrain = 10;
testdata.SubDefaults proto2_field = 11;
map<string, testdata.SubDefaults> proto2_value = 13;

google.protobuf.Any anything = 14;
repeated google.protobuf.Any many_things = 15;

Message submessage = 17;
repeated Message children = 18;
}

message Nested {
string bunny = 1;
bool cute = 2;
}

message MessageWithMap {
map<bool, bytes> byte_mapping = 1;
}


message IntMap {
map<int32, int32> rtt = 1;
}

message IntMaps {
repeated IntMap maps = 1;
}
17 changes: 17 additions & 0 deletions cmd/proto3fmt/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package main

import (
"log"
"os"

"github.com/emicklei/proto3"
)

func main() {
p := proto3.NewParser(os.Stdin)
def, err := p.Parse()
if err != nil {
log.Fatalln("proto3fmt failed:", p.Line(), err)
}
log.Printf("%#v", def)
}
6 changes: 3 additions & 3 deletions field.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"
)

// Field is a message field.
type Field struct {
Name string
Type string
Expand All @@ -14,8 +15,7 @@ type Field struct {
Sequence int
}

// parseField parsers one field.
func parseField(f *Field, p *Parser) error {
func (f *Field) parse(p *Parser) error {
for {
tok, lit := p.scanIgnoreWhitespace()
switch tok {
Expand All @@ -36,7 +36,7 @@ func parseField(f *Field, p *Parser) error {
f.Messages = append(f.Messages, m)
case REPEATED:
f.Repeated = true
return parseField(f, p)
return f.parse(p)
default:
goto done
}
Expand Down
2 changes: 1 addition & 1 deletion field_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ func TestRepeatedField(t *testing.T) {
proto := `repeated string lots = 1;`
p := NewParser(strings.NewReader(proto))
f := new(Field)
err := parseField(f, p)
err := f.parse(p)
if err != nil {
t.Fatal(err)
}
Expand Down
31 changes: 14 additions & 17 deletions import.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
package proto3

import (
"fmt"
"strings"
)
import "fmt"

// Import holds a filename to another .proto definition.
type Import struct {
Line int
Filename string
Kind string // weak, public
Kind string // weak, public, <empty>
}

func (i *Import) parse(p *Parser) error {
tok, lit := p.scanIgnoreWhitespace()
if tok != IDENT || !strings.Contains("weak public", lit) {
return fmt.Errorf("found %q, expected kind (weak|public)", lit)
}
i.Line = p.s.line
i.Kind = lit
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")
switch tok {
case WEAK:
i.Kind = lit
return i.parse(p)
case PUBLIC:
i.Kind = lit
return i.parse(p)
case QUOTE:
i.Filename = p.s.scanUntil('"')
default:
return fmt.Errorf("found %q, expected weak|public|quoted identifier", lit)
}
i.Filename = name
return nil
}
4 changes: 2 additions & 2 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Message struct {
func (m *Message) parse(p *Parser) error {
tok, lit := p.scanIgnoreWhitespace()
if tok != IDENT {
return fmt.Errorf("found %q, expected name", lit)
return fmt.Errorf("found %q, expected identifier", lit)
}
m.Name = lit
tok, lit = p.scanIgnoreWhitespace()
Expand All @@ -32,7 +32,7 @@ func (m *Message) parse(p *Parser) error {
default:
p.unscan()
f := new(Field)
err := parseField(f, p)
err := f.parse(p)
if err != nil {
return err
}
Expand Down
6 changes: 6 additions & 0 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ package proto3

import "fmt"

// Option is a protoc compiler option
type Option struct {
Line int
Name string
String string
Boolean bool
}

// accept dispatches the call to the visitor.
func (o *Option) accept(v Visitor) {
v.VisitOption(o)
}

func (o *Option) parse(p *Parser) error {
tok, lit := p.scanIgnoreWhitespace()
switch tok {
Expand Down
8 changes: 7 additions & 1 deletion package.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package proto3

// Package specifies the namespace for all proto elements.
type Package struct {
Name string
}

func (a *Package) parse(p *Parser) error {
// accept dispatches the call to the visitor.
func (p *Package) accept(v Visitor) {
v.VisitPackage(p)
}

func (p *Package) parse(pr *Parser) error {
return nil
}
5 changes: 4 additions & 1 deletion parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func NewParser(r io.Reader) *Parser {
// Parse parses a proto definition.
func (p *Parser) Parse() (*Proto, error) {
proto := new(Proto)
return proto, parseProto(proto, p)
return proto, proto.parse(p)
}

// scan returns the next token from the underlying scanner.
Expand Down Expand Up @@ -61,3 +61,6 @@ func (p *Parser) newComment(lit string) *Comment {
Message: lit,
}
}

// Line returns the line number on which the last token was read.
func (p *Parser) Line() int { return p.s.line }
9 changes: 5 additions & 4 deletions proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ func (c Comment) IsMultiline() bool {
return strings.Contains(c.Message, "\n")
}

// parseProto parsers a complete .proto definition source.
func parseProto(proto *Proto, p *Parser) error {
// parse parsers a complete .proto definition source.
func (proto *Proto) parse(p *Parser) error {
tok, lit := p.scanIgnoreWhitespace()
switch tok {
case COMMENT:
Expand All @@ -49,7 +49,8 @@ func parseProto(proto *Proto, p *Parser) error {
proto.Enums = append(proto.Enums, enum)
case SERVICE:
// TODO
service, err := parseService(p)
service := new(Service)
err := service.parse(p)
if err != nil {
return err
}
Expand All @@ -63,5 +64,5 @@ func parseProto(proto *Proto, p *Parser) error {
case EOF:
return nil
}
return parseProto(proto, p)
return proto.parse(p)
}
Loading

0 comments on commit 768352c

Please sign in to comment.