Skip to content

Commit 6eabacc

Browse files
author
Kazuyoshi Kato
committed
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 <[email protected]>
1 parent 58eb91e commit 6eabacc

4 files changed

Lines changed: 168 additions & 2 deletions

File tree

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"strings"
21+
22+
"google.golang.org/protobuf/compiler/protogen"
23+
)
24+
25+
// generator is a Go code generator that uses ttrpc.Server and ttrpc.Client.
26+
// Unlike the original gogo version, this doesn't generate serializers for message types and
27+
// let protoc-gen-go handle them.
28+
type generator struct {
29+
out *protogen.GeneratedFile
30+
31+
ident struct {
32+
context string
33+
server string
34+
client string
35+
method string
36+
}
37+
}
38+
39+
func newGenerator(out *protogen.GeneratedFile) *generator {
40+
gen := generator{out: out}
41+
gen.ident.context = out.QualifiedGoIdent(protogen.GoIdent{
42+
GoImportPath: "context",
43+
GoName: "Context",
44+
})
45+
gen.ident.server = out.QualifiedGoIdent(protogen.GoIdent{
46+
GoImportPath: "github.com/containerd/ttrpc",
47+
GoName: "Server",
48+
})
49+
gen.ident.client = out.QualifiedGoIdent(protogen.GoIdent{
50+
GoImportPath: "github.com/containerd/ttrpc",
51+
GoName: "Client",
52+
})
53+
gen.ident.method = out.QualifiedGoIdent(protogen.GoIdent{
54+
GoImportPath: "github.com/containerd/ttrpc",
55+
GoName: "Method",
56+
})
57+
return &gen
58+
}
59+
60+
func generate(plugin *protogen.Plugin, input *protogen.File) error {
61+
file := plugin.NewGeneratedFile(input.GeneratedFilenamePrefix+"_ttrpc.pb.go", input.GoImportPath)
62+
file.P("// Code generated by protoc-gen-go-ttrpc. DO NOT EDIT.")
63+
file.P("// source: ", input.Desc.Path())
64+
file.P("package ", input.GoPackageName)
65+
66+
gen := newGenerator(file)
67+
for _, service := range input.Services {
68+
gen.genService(service)
69+
}
70+
return nil
71+
}
72+
73+
func (gen *generator) genService(service *protogen.Service) {
74+
fullName := service.Desc.FullName()
75+
p := gen.out
76+
77+
serviceName := service.GoName + "Service"
78+
p.P("type ", serviceName, " interface{")
79+
for _, method := range service.Methods {
80+
p.P(method.GoName,
81+
"(ctx ", gen.ident.context, ",",
82+
"req *", method.Input.GoIdent, ")",
83+
"(*", method.Output.GoIdent, ", error)")
84+
}
85+
p.P("}")
86+
87+
// registration method
88+
p.P("func Register", serviceName, "(srv *", gen.ident.server, ", svc ", serviceName, "){")
89+
p.P(`srv.Register("`, fullName, `", map[string]`, gen.ident.method, "{")
90+
for _, method := range service.Methods {
91+
p.P(`"`, method.GoName, `": func(ctx `, gen.ident.context, ", unmarshal func(interface{}) error)(interface{}, error){")
92+
p.P("var req ", method.Input.GoIdent)
93+
p.P("if err := unmarshal(&req); err != nil {")
94+
p.P("return nil, err")
95+
p.P("}")
96+
p.P("return svc.", method.GoName, "(ctx, &req)")
97+
p.P("},")
98+
}
99+
p.P("})")
100+
p.P("}")
101+
102+
clientType := service.GoName + "Client"
103+
clientStructType := strings.ToLower(clientType[:1]) + clientType[1:]
104+
p.P("type ", clientStructType, " struct{")
105+
p.P("client *", gen.ident.client)
106+
p.P("}")
107+
p.P("func New", clientType, "(client *", gen.ident.client, ")", serviceName, "{")
108+
p.P("return &", clientStructType, "{")
109+
p.P("client:client,")
110+
p.P("}")
111+
p.P("}")
112+
113+
for _, method := range service.Methods {
114+
p.P("func (c *", clientStructType, ")", method.GoName, "(",
115+
"ctx ", gen.ident.context, ",",
116+
"req *", method.Input.GoIdent, ")",
117+
"(*", method.Output.GoIdent, ", error){")
118+
p.P("var resp ", method.Output.GoIdent)
119+
p.P(`if err := c.client.Call(ctx, "`, fullName, `", "`, method.Desc.Name(), `", req, &resp); err != nil {`)
120+
p.P("return nil, err")
121+
p.P("}")
122+
p.P("return &resp, nil")
123+
p.P("}")
124+
}
125+
}

cmd/protoc-gen-go-ttrpc/main.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"google.golang.org/protobuf/compiler/protogen"
21+
)
22+
23+
func main() {
24+
protogen.Options{}.Run(func(gen *protogen.Plugin) error {
25+
for _, f := range gen.Files {
26+
if !f.Generate {
27+
continue
28+
}
29+
if err := generate(gen, f); err != nil {
30+
return err
31+
}
32+
}
33+
return nil
34+
})
35+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ require (
99
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
1010
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63
1111
google.golang.org/grpc v1.27.1
12+
google.golang.org/protobuf v1.27.1
1213
)

go.sum

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
1313
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
1414
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
1515
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
16-
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
1716
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
17+
github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
18+
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
1819
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
19-
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
2020
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
21+
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
22+
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
2123
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
2224
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
2325
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
9092
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
9193
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
9294
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
95+
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
96+
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
97+
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
9398
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
9499
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

0 commit comments

Comments
 (0)