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

Add support extended google.api.annotations with response field #39

Merged
merged 12 commits into from
Aug 6, 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ _testmain.go
/integration/**/*.pb.*go
# Unignore some files, used in tests
!/integration/impl_exists/strings/strings.pb.impl.go
!/integration/binding_with_body_and_response/strings/strings.pb.impl.go

# Ignore vendor, needed for better local development
vendor/
2 changes: 1 addition & 1 deletion cmd/protoc-gen-goclay/genhandler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ func (g *Generator) getDescTemplate(swagger []byte, f *descriptor.File) (string,
"github.com/utrack/clay/v2/transport/httptransport",
"github.com/utrack/clay/v2/transport/swagger",
"github.com/grpc-ecosystem/grpc-gateway/runtime",
"github.com/grpc-ecosystem/grpc-gateway/utilities",
"google.golang.org/grpc",
"github.com/go-chi/chi",
}
Expand Down Expand Up @@ -320,7 +321,6 @@ func getPackage(path, gopath, gopkg string) string {
}
}


func hasBindings(service *descriptor.Service) bool {
for _, m := range service.Methods {
if len(m.Bindings) > 0 {
Expand Down
54 changes: 36 additions & 18 deletions cmd/protoc-gen-goclay/genhandler/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package genhandler

import (
"bytes"
"fmt"
"strings"
"text/template"

pbdescriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
"github.com/golang/protobuf/protoc-gen-go/generator"
"github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"github.com/pkg/errors"
)

Expand All @@ -17,6 +19,13 @@ var (

var pkg map[string]string

func getPkg(name string) string {
if p, ok := pkg[name]; ok && p != "" {
return p + "."
}
return ""
}

type param struct {
*descriptor.File
Imports []descriptor.GoPackage
Expand Down Expand Up @@ -108,13 +117,30 @@ var (
return strings.Join(ret, "/")
},
// returns safe package prefix with dot(.) or empty string by imported package name or alias
"pkg": func(name string) string {
if p, ok := pkg[name]; ok && p != "" {
return p + "."
"pkg": getPkg,
"hasBindings": hasBindings,
"responseBodyAware": func(binding interface{}) bool {
_, ok := binding.(interface {
ResponseBody() *descriptor.Body
})
return ok
},
"NewQueryParamFilter": func(b descriptor.Binding) string {
var seqs [][]string
if b.Body != nil {
seqs = append(seqs, strings.Split(b.Body.FieldPath.String(), "."))
}
return ""
for _, p := range b.PathParams {
seqs = append(seqs, strings.Split(p.FieldPath.String(), "."))
}
arr := utilities.NewDoubleArray(seqs)
encodings := make([]string, len(arr.Encoding))
for str, enc := range arr.Encoding {
encodings[enc] = fmt.Sprintf("%q: %d", str, enc)
}
e := strings.Join(encodings, ", ")
return fmt.Sprintf("&%sDoubleArray{Encoding: map[string]int{%s}, Base: %#v, Check: %#v}", getPkg("utilities"), e, arr.Base, arr.Check)
},
"hasBindings": hasBindings,
}

headerTemplate = template.Must(template.New("header").Funcs(funcMap).Parse(`
Expand Down Expand Up @@ -147,6 +173,7 @@ var _ {{ pkg "errors" }}Frame
var _ {{ pkg "httpruntime" }}Marshaler
var _ {{ pkg "http" }}Handler
var _ {{ pkg "httptransport" }}MarshalerError
var _ {{ pkg "utilities" }}DoubleArray
`))

footerTemplate = template.Must(template.New("footer").Funcs(funcMap).Parse(`
Expand All @@ -172,11 +199,7 @@ var (
}

{{ if not (hasAsterisk $b.ExplicitParams) }}
unmarshaler_goclay_{{ $svc.GetName }}_{{ $m.GetName }}_{{ $b.Index }}_boundParams = map[string]struct{}{
{{ range $n := $b.ExplicitParams -}}
"{{ $n }}": struct{}{},
{{ end }}
}
unmarshaler_goclay_{{ $svc.GetName }}_{{ $m.GetName }}_{{ $b.Index }}_boundParams = {{ NewQueryParamFilter $b }}
{{ end }}
{{ end }}
{{ end }}
Expand All @@ -197,14 +220,9 @@ var (
req := rif.(*{{$m.RequestType.GoType $m.Service.File.GoPkg.Path }})

{{ if not (hasAsterisk $b.ExplicitParams) }}
for k,v := range r.URL.Query() {
if _,ok := unmarshaler_goclay_{{ $svc.GetName }}_{{ $m.GetName }}_{{ $b.Index }}_boundParams[{{ pkg "strings" }}ToLower(k)];ok {
continue
}
if err := {{ pkg "errors" }}Wrap({{ pkg "runtime" }}PopulateFieldFromPath(req, k, v[0]), "couldn't populate field from Path"); err != nil {
return {{ pkg "httpruntime" }}TransformUnmarshalerError(err)
}
}
if err := {{ pkg "errors" }}Wrap({{ pkg "runtime" }}PopulateQueryParameters(req, r.URL.Query(), unmarshaler_goclay_{{ $svc.GetName }}_{{ $m.GetName }}_{{ $b.Index }}_boundParams),"couldn't populate query parameters"); err != nil {
return {{ pkg "httpruntime" }}TransformUnmarshalerError(err)
}
{{ end }}
{{- if $b.Body -}}
{{- template "unmbody" . -}}
Expand Down
11 changes: 10 additions & 1 deletion cmd/protoc-gen-goclay/genhandler/tpl_servicedesc.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,16 @@ func (d *{{ $svc.GetName }}Desc) RegisterHTTP(mux {{ pkg "transport" }}Router) {

_,outbound := {{ pkg "httpruntime" }}MarshalerForRequest(r)
w.Header().Set("Content-Type", outbound.ContentType())
err = outbound.Marshal(w, rsp)
{{ if $b | responseBodyAware -}}
{{ if $b.ResponseBody -}}
xrsp := rsp.(*{{$m.ResponseType.GoType $m.Service.File.GoPkg.Path }})
err = outbound.Marshal(w, {{ $b.ResponseBody.AssignableExpr "xrsp" }})
{{ else -}}
err = outbound.Marshal(w, rsp)
{{ end -}}
{{ else -}}
err = outbound.Marshal(w, rsp)
{{ end -}}
if err != nil {
{{ pkg "httpruntime" }}SetError(r.Context(),r,w,{{ pkg "errors" }}Wrap(err,"couldn't write response"))
return
Expand Down
14 changes: 13 additions & 1 deletion cmd/protoc-gen-goclay/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ func main() {
}
}

// Support replacing grpc-gateway by this fork: https://github.com/doroginin/grpc-gateway@v1.5.0-alpha2
// Also see PR: https://github.com/grpc-ecosystem/grpc-gateway/pull/712
var xreg interface{} = reg
// Permits repeated field in body field path of `google.api.http` annotation option
if set, ok := xreg.(interface{ SetAllowRepeatedFieldsInBody(bool) }); ok {
set.SetAllowRepeatedFieldsInBody(true)
}
// Use Field.GetJsonName() for generating swagger definitions
if set, ok := xreg.(interface{ SetUseJSONNameInSwaggerDef(bool) }); ok {
set.SetUseJSONNameInSwaggerDef(true)
}
reg.SetAllowDeleteBody(*allowDeleteBody)
reg.SetPrefix(*importPrefix)
for k, v := range pkgMap {
reg.AddPkgMap(k, v)
Expand All @@ -83,7 +95,7 @@ func main() {
}

if *withSwagger {
swagBuf, err := genSwaggerDef(req, pkgMap)
swagBuf, err := genSwaggerDef(reg, req)
if err != nil {
emitError(err)
return
Expand Down
22 changes: 1 addition & 21 deletions cmd/protoc-gen-goclay/swagger.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,8 @@ import (
"github.com/utrack/grpc-gateway/protoc-gen-swagger/genswagger"
)

func genSwaggerDef(req *plugin.CodeGeneratorRequest, pkgMap map[string]string) (map[string][]byte, error) {
reg := descriptor.NewRegistry()
reg.SetPrefix(*importPrefix)
reg.SetAllowDeleteBody(*allowDeleteBody)

for k, v := range pkgMap {
reg.AddPkgMap(k, v)
}

if *grpcAPIConfiguration != "" {
if err := reg.LoadGrpcAPIServiceFromYAML(*grpcAPIConfiguration); err != nil {
return nil, err
}
}

func genSwaggerDef(reg *descriptor.Registry, req *plugin.CodeGeneratorRequest) (map[string][]byte, error) {
gsw := genswagger.New(reg)

if err := reg.Load(req); err != nil {
return nil, err
}

var targets []*descriptor.File
for _, target := range req.FileToGenerate {
f, err := reg.LookupFile(target)
Expand All @@ -36,7 +17,6 @@ func genSwaggerDef(req *plugin.CodeGeneratorRequest, pkgMap map[string]string) (
}
targets = append(targets, f)
}

outSwag, err := gsw.Generate(targets)
if err != nil {
return nil, err
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ require (
github.com/PuerkitoBio/purell v1.1.0 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/doroginin/grpc-gateway v1.4.1 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-chi/chi v0.0.0-20171222161133-e83ac2304db3
github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa // indirect
Expand Down
5 changes: 1 addition & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/doroginin/grpc-gateway v1.4.1/go.mod h1:xGf12DmL9dDcOi1rEZ6SGm9BF7PnHWbcPSzsSq2P1hw=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-chi/chi v0.0.0-20171222161133-e83ac2304db3 h1:EJsFVtoBv7ShDubFUW5uGJl18UkJktfyajiSArb9KEQ=
Expand Down Expand Up @@ -46,7 +47,6 @@ github.com/utrack/grpc-gateway v0.0.0-20180624180524-fabb4258c392 h1:pDx+PFU58jI
github.com/utrack/grpc-gateway v0.0.0-20180624180524-fabb4258c392/go.mod h1:rGEy5AL6nrZOtcF8LDYwX6SM4vbI0i6M5vu99VMEO2s=
golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8 h1:h7zdf0RiEvWbYBKIx4b+q41xoUVnMmvsGZnIVE5syG8=
golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20180621144259-afe8f62b1d6b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180629035331-4cb1c02c05b0 h1:eOjEPieBzQ+rKOvQTqwbkm/0BdWz2JQwUzaa97tcZ8k=
golang.org/x/net v0.0.0-20180629035331-4cb1c02c05b0/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
Expand All @@ -55,8 +55,6 @@ golang.org/x/sys v0.0.0-20180709060233-1b2967e3c290 h1:lPmtvIvpa5gZbfK5Ms5fXR7KN
golang.org/x/sys v0.0.0-20180709060233-1b2967e3c290/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
google.golang.org/genproto v0.0.0-20180621235812-80063a038e33 h1:ECqAoHgIeu1vSTee2QoM8moQG9eBjUg+L8lKrgKC4Ig=
google.golang.org/genproto v0.0.0-20180621235812-80063a038e33/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180627194029-ff3583edef7d h1:6X4PYh39/Pjz7al8CnTTsk+jp3fG2KPpusrnwqzAW+M=
google.golang.org/genproto v0.0.0-20180627194029-ff3583edef7d/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.13.0 h1:bHIbVsCwmvbArgCJmLdgOdHFXlKqTOVjbibbS19cXHc=
Expand All @@ -65,7 +63,6 @@ gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNat
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
Expand Down
34 changes: 3 additions & 31 deletions integration/Makefile
Original file line number Diff line number Diff line change
@@ -1,36 +1,8 @@
GOPATH?=$(HOME)/go
FIRST_GOPATH:=$(firstword $(subst :, ,$(GOPATH)))
GOBIN:=$(FIRST_GOPATH)/bin
include env.mk

LOCAL_BIN:=$(CURDIR)/bin
GEN_CLAY_BIN:=$(CURDIR)/bin/protoc-gen-goclay
export GEN_CLAY_BIN
GEN_GO_BIN:=$(CURDIR)/bin/protoc-gen-go
export GEN_GO_BIN
GEN_GOFAST_BIN:=$(CURDIR)/bin/protoc-gen-gofast
export GEN_GOFAST_BIN
GEN_GOGOFAST_BIN:=$(CURDIR)/bin/protoc-gen-gogofast
export GEN_GOGOFAST_BIN
all: clean protoc-build test

GRPC_GATEWAY_PKG:=$(shell vgo list -m all | grep github.com/grpc-ecosystem/grpc-gateway | awk '{print ($$4 != "" ? $$4 : $$1)}')
GRPC_GATEWAY_VERSION:=$(shell vgo list -m all | grep github.com/grpc-ecosystem/grpc-gateway | awk '{print ($$5 != "" ? $$5 : $$2)}')
GRPC_GATEWAY_PATH:=${FIRST_GOPATH}/src/mod/${GRPC_GATEWAY_PKG}@${GRPC_GATEWAY_VERSION}
export GRPC_GATEWAY_PATH

all: clean build test

GREEN=\033[0;32m
RED=\033[0;31m
NC=\033[0m

build:
$(info #Installing binary dependencies...)
GOBIN=$(LOCAL_BIN) vgo install github.com/utrack/clay/v2/cmd/protoc-gen-goclay
GOBIN=$(LOCAL_BIN) vgo install github.com/golang/protobuf/protoc-gen-go
GOBIN=$(LOCAL_BIN) vgo install github.com/gogo/protobuf/protoc-gen-gofast
GOBIN=$(LOCAL_BIN) vgo install github.com/gogo/protobuf/protoc-gen-gogofast

test: build
test: protoc-build
@ \
success=0; \
failure=0; \
Expand Down
8 changes: 2 additions & 6 deletions integration/additional_bindings/Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
GOPATH?=$(HOME)/go
FIRST_GOPATH:=$(firstword $(subst :, ,$(GOPATH)))
GRPC_GATEWAY_PATH?=${FIRST_GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway
GEN_CLAY_BIN?=$(shell which protoc-gen-goclay)
GEN_GOFAST_BIN?=$(shell which protoc-gen-gofast)
include ../env.mk

pwd:
@pwd
Expand All @@ -11,7 +7,7 @@ clean:
find . -regex "\.\/.*\/.*\.go" -exec rm {} +
rm -f main

protoc:
protoc: protoc-build
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't like this protoc-build in every sub-test - maybe it's better to run them once in the core Makefile.

And if you want to run a single test individually - just prepare your environment manually running make protoc-build and then run make test.

Copy link
Contributor

Choose a reason for hiding this comment

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

or we could do even better and make 2 targets.
test would explicitly run protoc-build - you would use it in manuall run
test-ci won't call protoc-build - it would be used in the core Makefile to run all tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

discussed verbally

protoc --plugin=protoc-gen-goclay=$(GEN_CLAY_BIN) --plugin=protoc-gen-gofast=$(GEN_GOFAST_BIN) -I/usr/local/include:${GRPC_GATEWAY_PATH}/third_party/googleapis:. --gofast_out=plugins=grpc:. --goclay_out=impl=true,impl_path=../strings:. pb/strings.proto

build:
Expand Down
24 changes: 24 additions & 0 deletions integration/binding_with_body_and_response/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
include ../env.mk

$(shell vgo mod -sync)
$(shell vgo get github.com/googleapis/googleapis)
GOOGLEAPIS_PKG:=$(shell vgo list -m all | grep github.com/googleapis/googleapis | awk '{print ($$4 != "" ? $$4 : $$1)}')
GOOGLEAPIS_VERSION:=$(shell vgo list -m all | grep github.com/googleapis/googleapis | awk '{print ($$5 != "" ? $$5 : $$2)}')
GOOGLEAPIS_PATH:=${FIRST_GOPATH}/src/mod/${GOOGLEAPIS_PKG}@${GOOGLEAPIS_VERSION}

pwd:
@pwd

clean:
rm -f ./pb/strings.pb.go
rm -f ./pb/strings.pb.goclay.go
rm -f main

protoc: protoc-build
protoc --plugin=protoc-gen-goclay=$(GEN_CLAY_BIN) --plugin=protoc-gen-gofast=$(GEN_GOFAST_BIN) -I/usr/local/include:${GOOGLEAPIS_PATH}:. --gofast_out=plugins=grpc:. --goclay_out=impl=true,impl_path=../strings:. pb/strings.proto

build:
vgo build -o main main.go

test: pwd clean protoc build
vgo test -v main_test.go
24 changes: 24 additions & 0 deletions integration/binding_with_body_and_response/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module github.com/utrack/clay/integration/binding_with_body_and_response

replace github.com/grpc-ecosystem/grpc-gateway => github.com/doroginin/grpc-gateway v1.5.0-alpha3

replace github.com/utrack/grpc-gateway => github.com/doroginin/grpc-gateway v1.5.0-alpha3

replace github.com/googleapis/googleapis => github.com/doroginin/googleapis v0.0.0-20180730132820-50a24711b667

replace google.golang.org/genproto => github.com/doroginin/go-genproto v0.0.0-20180730134020-8126e81001e3

replace github.com/utrack/clay/v2 => ../..

require (
github.com/go-chi/chi v0.0.0-20171222161133-e83ac2304db3
github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee
github.com/golang/protobuf v1.1.0
github.com/googleapis/googleapis v0.0.0-20180726215759-201d7be7f9da // indirect
github.com/grpc-ecosystem/grpc-gateway v1.4.1
github.com/pkg/errors v0.8.0
github.com/utrack/clay/v2 v2.1.0
golang.org/x/net v0.0.0-20180629035331-4cb1c02c05b0
google.golang.org/genproto v0.0.0-20180627194029-ff3583edef7d
google.golang.org/grpc v1.13.0
)
Loading