forked from goadesign/goa
/
client_types.go
111 lines (104 loc) · 2.99 KB
/
client_types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package codegen
import (
"path"
"path/filepath"
"goa.design/goa/codegen"
"goa.design/goa/expr"
)
// ClientTypeFiles returns the types file for every gRPC service that contain
// constructors to transform:
//
// * service payload types into protocol buffer request message types
// * protocol buffer response message types into service result types
func ClientTypeFiles(genpkg string, root *expr.RootExpr) []*codegen.File {
fw := make([]*codegen.File, len(root.API.GRPC.Services))
seen := make(map[string]struct{})
for i, r := range root.API.GRPC.Services {
fw[i] = clientType(genpkg, r, seen)
}
return fw
}
// clientType returns the file containing the constructor functions to
// transform the service payload types to the corresponding gRPC request types
// and gRPC response types to the corresponding service result types.
//
// seen keeps track of the constructor names that have already been generated
// to prevent duplicate code generation.
func clientType(genpkg string, svc *expr.GRPCServiceExpr, seen map[string]struct{}) *codegen.File {
var (
initData []*InitData
sd = GRPCServices.Get(svc.Name())
)
{
collect := func(c *ConvertData) {
if c.Init != nil {
initData = append(initData, c.Init)
}
}
for _, a := range svc.GRPCEndpoints {
ed := sd.Endpoint(a.Name())
if c := ed.Request.ClientConvert; c != nil {
collect(c)
}
if c := ed.Response.ClientConvert; c != nil {
collect(c)
}
if ed.ClientStream != nil {
if c := ed.ClientStream.RecvConvert; c != nil {
collect(c)
}
if c := ed.ClientStream.SendConvert; c != nil {
collect(c)
}
}
for _, e := range ed.Errors {
if c := e.Response.ClientConvert; c != nil {
collect(c)
}
}
}
}
var (
fpath string
sections []*codegen.SectionTemplate
)
{
svcName := codegen.SnakeCase(sd.Service.VarName)
fpath = filepath.Join(codegen.Gendir, "grpc", svcName, "client", "types.go")
sections = []*codegen.SectionTemplate{
codegen.Header(svc.Name()+" gRPC client types", "client",
[]*codegen.ImportSpec{
{Path: "unicode/utf8"},
{Path: "goa.design/goa", Name: "goa"},
{Path: path.Join(genpkg, svcName), Name: sd.Service.PkgName},
{Path: path.Join(genpkg, svcName, "views"), Name: sd.Service.ViewsPkg},
{Path: path.Join(genpkg, "grpc", svcName, pbPkgName), Name: sd.PkgName},
}),
}
for _, init := range initData {
sections = append(sections, &codegen.SectionTemplate{
Name: "client-type-init",
Source: typeInitT,
Data: init,
})
}
for _, data := range sd.validations {
if data.Kind == validateServer {
continue
}
sections = append(sections, &codegen.SectionTemplate{
Name: "client-validate",
Source: validateT,
Data: data,
})
}
for _, h := range sd.transformHelpers {
sections = append(sections, &codegen.SectionTemplate{
Name: "client-transform-helper",
Source: transformHelperT,
Data: h,
})
}
}
return &codegen.File{Path: fpath, SectionTemplates: sections}
}