Add protoc-gen-go-ttrpc
Google's new protobuf code generator only supports protobuf serialization/deserialization and let other code generators handle RPC-related aspects. This new code generator follows the change and can be used with the new protobuf code generator. Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
This commit is contained in:
parent
58eb91eddb
commit
6eabacc9bc
125
cmd/protoc-gen-go-ttrpc/generator.go
Normal file
125
cmd/protoc-gen-go-ttrpc/generator.go
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"google.golang.org/protobuf/compiler/protogen"
|
||||
)
|
||||
|
||||
// generator is a Go code generator that uses ttrpc.Server and ttrpc.Client.
|
||||
// Unlike the original gogo version, this doesn't generate serializers for message types and
|
||||
// let protoc-gen-go handle them.
|
||||
type generator struct {
|
||||
out *protogen.GeneratedFile
|
||||
|
||||
ident struct {
|
||||
context string
|
||||
server string
|
||||
client string
|
||||
method string
|
||||
}
|
||||
}
|
||||
|
||||
func newGenerator(out *protogen.GeneratedFile) *generator {
|
||||
gen := generator{out: out}
|
||||
gen.ident.context = out.QualifiedGoIdent(protogen.GoIdent{
|
||||
GoImportPath: "context",
|
||||
GoName: "Context",
|
||||
})
|
||||
gen.ident.server = out.QualifiedGoIdent(protogen.GoIdent{
|
||||
GoImportPath: "github.com/containerd/ttrpc",
|
||||
GoName: "Server",
|
||||
})
|
||||
gen.ident.client = out.QualifiedGoIdent(protogen.GoIdent{
|
||||
GoImportPath: "github.com/containerd/ttrpc",
|
||||
GoName: "Client",
|
||||
})
|
||||
gen.ident.method = out.QualifiedGoIdent(protogen.GoIdent{
|
||||
GoImportPath: "github.com/containerd/ttrpc",
|
||||
GoName: "Method",
|
||||
})
|
||||
return &gen
|
||||
}
|
||||
|
||||
func generate(plugin *protogen.Plugin, input *protogen.File) error {
|
||||
file := plugin.NewGeneratedFile(input.GeneratedFilenamePrefix+"_ttrpc.pb.go", input.GoImportPath)
|
||||
file.P("// Code generated by protoc-gen-go-ttrpc. DO NOT EDIT.")
|
||||
file.P("// source: ", input.Desc.Path())
|
||||
file.P("package ", input.GoPackageName)
|
||||
|
||||
gen := newGenerator(file)
|
||||
for _, service := range input.Services {
|
||||
gen.genService(service)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gen *generator) genService(service *protogen.Service) {
|
||||
fullName := service.Desc.FullName()
|
||||
p := gen.out
|
||||
|
||||
serviceName := service.GoName + "Service"
|
||||
p.P("type ", serviceName, " interface{")
|
||||
for _, method := range service.Methods {
|
||||
p.P(method.GoName,
|
||||
"(ctx ", gen.ident.context, ",",
|
||||
"req *", method.Input.GoIdent, ")",
|
||||
"(*", method.Output.GoIdent, ", error)")
|
||||
}
|
||||
p.P("}")
|
||||
|
||||
// registration method
|
||||
p.P("func Register", serviceName, "(srv *", gen.ident.server, ", svc ", serviceName, "){")
|
||||
p.P(`srv.Register("`, fullName, `", map[string]`, gen.ident.method, "{")
|
||||
for _, method := range service.Methods {
|
||||
p.P(`"`, method.GoName, `": func(ctx `, gen.ident.context, ", unmarshal func(interface{}) error)(interface{}, error){")
|
||||
p.P("var req ", method.Input.GoIdent)
|
||||
p.P("if err := unmarshal(&req); err != nil {")
|
||||
p.P("return nil, err")
|
||||
p.P("}")
|
||||
p.P("return svc.", method.GoName, "(ctx, &req)")
|
||||
p.P("},")
|
||||
}
|
||||
p.P("})")
|
||||
p.P("}")
|
||||
|
||||
clientType := service.GoName + "Client"
|
||||
clientStructType := strings.ToLower(clientType[:1]) + clientType[1:]
|
||||
p.P("type ", clientStructType, " struct{")
|
||||
p.P("client *", gen.ident.client)
|
||||
p.P("}")
|
||||
p.P("func New", clientType, "(client *", gen.ident.client, ")", serviceName, "{")
|
||||
p.P("return &", clientStructType, "{")
|
||||
p.P("client:client,")
|
||||
p.P("}")
|
||||
p.P("}")
|
||||
|
||||
for _, method := range service.Methods {
|
||||
p.P("func (c *", clientStructType, ")", method.GoName, "(",
|
||||
"ctx ", gen.ident.context, ",",
|
||||
"req *", method.Input.GoIdent, ")",
|
||||
"(*", method.Output.GoIdent, ", error){")
|
||||
p.P("var resp ", method.Output.GoIdent)
|
||||
p.P(`if err := c.client.Call(ctx, "`, fullName, `", "`, method.Desc.Name(), `", req, &resp); err != nil {`)
|
||||
p.P("return nil, err")
|
||||
p.P("}")
|
||||
p.P("return &resp, nil")
|
||||
p.P("}")
|
||||
}
|
||||
}
|
35
cmd/protoc-gen-go-ttrpc/main.go
Normal file
35
cmd/protoc-gen-go-ttrpc/main.go
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/compiler/protogen"
|
||||
)
|
||||
|
||||
func main() {
|
||||
protogen.Options{}.Run(func(gen *protogen.Plugin) error {
|
||||
for _, f := range gen.Files {
|
||||
if !f.Generate {
|
||||
continue
|
||||
}
|
||||
if err := generate(gen, f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
1
go.mod
1
go.mod
@ -9,4 +9,5 @@ require (
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63
|
||||
google.golang.org/grpc v1.27.1
|
||||
google.golang.org/protobuf v1.27.1
|
||||
)
|
||||
|
9
go.sum
9
go.sum
@ -13,11 +13,13 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@ -90,5 +92,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
Loading…
Reference in New Issue
Block a user