Skip to content

Commit

Permalink
Build AST from FileDescriptorSet (#48)
Browse files Browse the repository at this point in the history
* Build AST from FileDescriptorSet

* checkpoint
  • Loading branch information
rodaine authored Feb 5, 2019
1 parent 2c3370e commit 2c275d2
Show file tree
Hide file tree
Showing 26 changed files with 85 additions and 44 deletions.
10 changes: 1 addition & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
# vendored code
vendor/

# binaries
bin/

# coverage reports
cover.*


testdata/fdset.bin
testdata/generated/
**/*.pb.go
**/code_generator_request.pb.bin

# ide file
.idea/
.vscode/
14 changes: 10 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ lint: # lints the package for common code smells
go vet -all -shadow -shadowstrict $(PKGS)

.PHONY: quick
quick: vendor # runs all tests without the race detector or coverage
quick: vendor testdata # runs all tests without the race detector or coverage
go test $(PKGS)

.PHONY: tests
tests: vendor # runs all tests against the package with race detection and coverage percentage
tests: vendor testdata # runs all tests against the package with race detection and coverage percentage
go test -race -cover $(PKGS)

.PHONY: cover
cover: vendor # runs all tests against the package, generating a coverage report and opening it in the browser
cover: vendor testdata # runs all tests against the package, generating a coverage report and opening it in the browser
go test -race -covermode=atomic -coverprofile=cover.out $(PKGS) || true
go tool cover -html cover.out -o cover.html
open cover.html
Expand All @@ -35,7 +35,7 @@ docs: # starts a doc server and opens a browser window to this package
godoc -http=localhost:6060

.PHONY: testdata
testdata: testdata-graph testdata-go testdata/generated # generate all testdata
testdata: testdata-graph testdata-go testdata/generated testdata/fdset.bin # generate all testdata

.PHONY: testdata-graph
testdata-graph: bin/protoc-gen-debug # parses the proto file sets in testdata/graph and renders binary CodeGeneratorRequest
Expand Down Expand Up @@ -65,6 +65,12 @@ testdata/generated: protoc-gen-go bin/protoc-gen-example
`find $$subdir -name "*.proto"`; \
done

testdata/fdset.bin:
@protoc -I ./testdata/protos \
-o ./testdata/fdset.bin \
--include_imports \
testdata/protos/**/*.proto

.PHONY: testdata-go
testdata-go: protoc-gen-go bin/protoc-gen-debug # generate go-specific testdata
cd lang/go && $(MAKE) \
Expand Down
2 changes: 1 addition & 1 deletion artifact.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"strings"

"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/plugin"
plugin_go "github.com/golang/protobuf/protoc-gen-go/plugin"
)

// An Artifact describes the output for a Module. Typically this is the creation
Expand Down
24 changes: 22 additions & 2 deletions ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,14 @@ func (g *graph) Lookup(name string) (Entity, bool) {
return e, ok
}

// ProcessDescriptors converts a CodeGeneratorRequest from protoc into a fully
// connected AST entity graph. An error is returned if the input is malformed.
// ProcessDescriptors is deprecated; use ProcessCodeGeneratorRequest instead
func ProcessDescriptors(debug Debugger, req *plugin_go.CodeGeneratorRequest) AST {
return ProcessCodeGeneratorRequest(debug, req)
}

// ProcessCodeGeneratorRequest converts a CodeGeneratorRequest from protoc into a fully
// connected AST entity graph. An error is returned if the input is malformed.
func ProcessCodeGeneratorRequest(debug Debugger, req *plugin_go.CodeGeneratorRequest) AST {
g := &graph{
d: debug,
targets: make(map[string]File, len(req.GetFileToGenerate())),
Expand All @@ -62,6 +67,21 @@ func ProcessDescriptors(debug Debugger, req *plugin_go.CodeGeneratorRequest) AST
return g
}

// ProcessFileDescriptorSet conversts a FileDescriptorSet from protoc into a
// fully connected AST entity graph. An error is returned if the input is
// malformed or missing dependencies. To generate a self-contained
// FileDescriptorSet, run the following command:
//
// protoc -o path/to/fdset.bin --include_imports $PROTO_FILES
//
// The emitted AST will have no values in the Targets map, but Packages will be
// populated. If used for testing purposes, the Targets map can be manually
// populated.
func ProcessFileDescriptorSet(debug Debugger, fdset *descriptor.FileDescriptorSet) AST {
req := plugin_go.CodeGeneratorRequest{ProtoFile: fdset.File}
return ProcessCodeGeneratorRequest(debug, &req)
}

func (g *graph) hydratePackage(f *descriptor.FileDescriptorProto) Package {
lookup := f.GetPackage()
if pkg, exists := g.packages[lookup]; exists {
Expand Down
26 changes: 25 additions & 1 deletion ast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"path/filepath"
"testing"

"github.com/golang/protobuf/protoc-gen-go/descriptor"

"github.com/golang/protobuf/proto"
plugin_go "github.com/golang/protobuf/protoc-gen-go/plugin"
"github.com/stretchr/testify/assert"
Expand All @@ -24,13 +26,35 @@ func readCodeGenReq(t *testing.T, dir string) *plugin_go.CodeGeneratorRequest {
return req
}

func readFileDescSet(t *testing.T, filename string) *descriptor.FileDescriptorSet {
data, err := ioutil.ReadFile(filename)
require.NoError(t, err, "unable to read FDS at %q", filename)

fdset := &descriptor.FileDescriptorSet{}
err = proto.Unmarshal(data, fdset)
require.NoError(t, err, "unable to unmarshal FDS data at %q", filename)

return fdset
}

func buildGraph(t *testing.T, dir string) AST {
d := InitMockDebugger()
ast := ProcessDescriptors(d, readCodeGenReq(t, dir))
ast := ProcessCodeGeneratorRequest(d, readCodeGenReq(t, dir))
require.False(t, d.Failed(), "failed to build graph (see previous log statements)")
return ast
}

func TestGraph_FDSet(t *testing.T) {
fdset := readFileDescSet(t, "testdata/fdset.bin")
d := InitMockDebugger()
ast := ProcessFileDescriptorSet(d, fdset)

require.False(t, d.Failed(), "failed to build graph from FDSet")
msg, found := ast.Lookup(".kitchen.Sink")
assert.True(t, found)
assert.Implements(t, (*Message)(nil), msg)
}

func TestGraph_Messages(t *testing.T) {
t.Parallel()
g := buildGraph(t, "messages")
Expand Down
2 changes: 1 addition & 1 deletion generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/descriptor"
"github.com/golang/protobuf/protoc-gen-go/plugin"
plugin_go "github.com/golang/protobuf/protoc-gen-go/plugin"
"github.com/stretchr/testify/assert"
)

Expand Down
2 changes: 1 addition & 1 deletion lang/go/context.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package pgsgo

import "github.com/lyft/protoc-gen-star"
import pgs "github.com/lyft/protoc-gen-star"

// Context resolves Go-specific language for Packages & Entities generated by
// protoc-gen-go. The rules that drive the naming behavior are complicated, and
Expand Down
2 changes: 1 addition & 1 deletion lang/go/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package pgsgo
import (
"testing"

"github.com/lyft/protoc-gen-star"
pgs "github.com/lyft/protoc-gen-star"
"github.com/stretchr/testify/assert"
)

Expand Down
2 changes: 1 addition & 1 deletion lang/go/gofmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"go/format"
"strings"

"github.com/lyft/protoc-gen-star"
pgs "github.com/lyft/protoc-gen-star"
)

type goFmt struct{}
Expand Down
2 changes: 1 addition & 1 deletion lang/go/gofmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package pgsgo
import (
"testing"

"github.com/lyft/protoc-gen-star"
pgs "github.com/lyft/protoc-gen-star"

"github.com/stretchr/testify/assert"
)
Expand Down
6 changes: 3 additions & 3 deletions lang/go/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"testing"

"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/plugin"
"github.com/lyft/protoc-gen-star"
plugin_go "github.com/golang/protobuf/protoc-gen-go/plugin"
pgs "github.com/lyft/protoc-gen-star"
"github.com/stretchr/testify/require"
)

Expand All @@ -28,7 +28,7 @@ func readCodeGenReq(t *testing.T, dir ...string) *plugin_go.CodeGeneratorRequest

func buildGraph(t *testing.T, dir ...string) pgs.AST {
d := pgs.InitMockDebugger()
ast := pgs.ProcessDescriptors(d, readCodeGenReq(t, dir...))
ast := pgs.ProcessCodeGeneratorRequest(d, readCodeGenReq(t, dir...))
require.False(t, d.Failed(), "failed to build graph (see previous log statements)")
return ast
}
Expand Down
2 changes: 1 addition & 1 deletion lang/go/name.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"unicode/utf8"

"github.com/golang/protobuf/protoc-gen-go/generator"
"github.com/lyft/protoc-gen-star"
pgs "github.com/lyft/protoc-gen-star"
)

func (c context) Name(node pgs.Node) pgs.Name {
Expand Down
2 changes: 1 addition & 1 deletion lang/go/name_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package pgsgo
import (
"testing"

"github.com/lyft/protoc-gen-star"
pgs "github.com/lyft/protoc-gen-star"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down
2 changes: 1 addition & 1 deletion lang/go/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"regexp"
"strings"

"github.com/lyft/protoc-gen-star"
pgs "github.com/lyft/protoc-gen-star"
)

var nonAlphaNumPattern = regexp.MustCompile("[^a-zA-Z0-9]")
Expand Down
2 changes: 1 addition & 1 deletion lang/go/package_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package pgsgo
import (
"testing"

"github.com/lyft/protoc-gen-star"
pgs "github.com/lyft/protoc-gen-star"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down
2 changes: 1 addition & 1 deletion lang/go/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"fmt"
"strings"

"github.com/lyft/protoc-gen-star"
pgs "github.com/lyft/protoc-gen-star"
)

const (
Expand Down
2 changes: 1 addition & 1 deletion lang/go/parameters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package pgsgo
import (
"testing"

"github.com/lyft/protoc-gen-star"
pgs "github.com/lyft/protoc-gen-star"
"github.com/stretchr/testify/assert"
)

Expand Down
2 changes: 1 addition & 1 deletion lang/go/type_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"fmt"
"strings"

"github.com/lyft/protoc-gen-star"
pgs "github.com/lyft/protoc-gen-star"
)

func (c context) Type(f pgs.Field) TypeName {
Expand Down
3 changes: 1 addition & 2 deletions lang/go/type_name_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import (
"fmt"
"testing"

pgs "github.com/lyft/protoc-gen-star"
"github.com/stretchr/testify/require"

"github.com/lyft/protoc-gen-star"

"github.com/stretchr/testify/assert"
)

Expand Down
2 changes: 1 addition & 1 deletion persister.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"strings"

"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/plugin"
plugin_go "github.com/golang/protobuf/protoc-gen-go/plugin"
"github.com/spf13/afero"
)

Expand Down
2 changes: 1 addition & 1 deletion protoc-gen-debug/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"path/filepath"

"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/plugin"
plugin_go "github.com/golang/protobuf/protoc-gen-go/plugin"
)

func main() {
Expand Down
4 changes: 2 additions & 2 deletions testdata/protoc-gen-example/jsonify.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package main
import (
"text/template"

"github.com/lyft/protoc-gen-star/lang/go"
pgsgo "github.com/lyft/protoc-gen-star/lang/go"

"github.com/lyft/protoc-gen-star"
pgs "github.com/lyft/protoc-gen-star"
)

// JSONifyPlugin adds encoding/json Marshaler and Unmarshaler methods on PB
Expand Down
4 changes: 2 additions & 2 deletions testdata/protoc-gen-example/main.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package main

import (
"github.com/lyft/protoc-gen-star"
"github.com/lyft/protoc-gen-star/lang/go"
pgs "github.com/lyft/protoc-gen-star"
pgsgo "github.com/lyft/protoc-gen-star/lang/go"
)

func main() {
Expand Down
2 changes: 1 addition & 1 deletion testdata/protoc-gen-example/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

"bytes"

"github.com/lyft/protoc-gen-star"
pgs "github.com/lyft/protoc-gen-star"
)

type PrinterModule struct {
Expand Down
4 changes: 2 additions & 2 deletions workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"sync"

"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/plugin"
plugin_go "github.com/golang/protobuf/protoc-gen-go/plugin"
)

type workflow interface {
Expand Down Expand Up @@ -38,7 +38,7 @@ func (wf *standardWorkflow) Init(g *Generator) AST {
pm(wf.params)
}

return ProcessDescriptors(g, req)
return ProcessCodeGeneratorRequest(g, req)
}

func (wf *standardWorkflow) Run(ast AST) (arts []Artifact) {
Expand Down
2 changes: 1 addition & 1 deletion workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"testing"

"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/plugin"
plugin_go "github.com/golang/protobuf/protoc-gen-go/plugin"
"github.com/stretchr/testify/assert"
)

Expand Down

0 comments on commit 2c275d2

Please sign in to comment.