-
Notifications
You must be signed in to change notification settings - Fork 0
/
generator-job.go
121 lines (98 loc) · 3.03 KB
/
generator-job.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
112
113
114
115
116
117
118
119
120
121
package goku
import (
"bytes"
"github.com/v1990/protoc-gen-goku/descriptors"
"path/filepath"
"strings"
"text/template"
)
func (g *Generator) generateFile(file *descriptors.FileDescriptorProto) {
defer g.Recover(nil)
fCtx := g.ctx.WithLoop(LoopFile, file)
g.executeJobs(fCtx)
for _, message := range file.GetMessageType() {
mCtx := fCtx.WithLoop(LoopMessage, message)
g.executeJobs(mCtx)
for _, nestedMessage := range message.GetNestedType() {
nmCtx := mCtx.WithLoop(LoopNestedMessage, nestedMessage)
g.executeJobs(nmCtx)
}
//
for _, enumObj := range message.GetEnumType() {
neCtx := mCtx.WithLoop(LoopNestedEnum, enumObj)
g.executeJobs(neCtx)
}
}
for _, enumObj := range file.GetEnumType() {
eCtx := fCtx.WithLoop(LoopEnum, enumObj)
g.executeJobs(eCtx)
}
for _, service := range file.GetService() {
sCtx := fCtx.WithLoop(LoopService, service)
g.executeJobs(sCtx)
for _, method := range service.GetMethod() {
mCtx := sCtx.WithLoop(LoopMethod, method)
g.executeJobs(mCtx)
}
}
}
func (g *Generator) executeJobs(ctx *Context) {
g.populateCtx(ctx)
jobs := g.getJobs(ctx)
//g.Debug("executeJobs: %s -> [%s] %s jobs: %d", ctx.GetFileName(), ctx.Loop(), ctx.object.GetName(), len(jobs))
for _, job := range jobs {
//g.Debug(strings.Repeat("*", 40))
//g.Debug("==== job: %s [Start]", job.name)
//g.Debug(" %+v", job)
//g.Debug("")
// 每个job都创建一个新的 ctx
g.executeJob(job, ctx.withJob(job))
//g.Debug("")
//g.Debug("==== job: %s [Done]", job.name)
//g.Debug(strings.Repeat("=", 40))
}
}
func (g *Generator) executeJob(job Job, ctx *Context) {
g.populateCtx(ctx)
outFileName := ctx.MustEval(job.Out)
g.Debug("execute job : %-18s %-25s %-30s ==> %s",
"["+ctx.Loop()+"]", ctx.Object().GetName(), job.Name, outFileName)
// 解析模板
var tpl *template.Template
var err error
if len(job.Template) > 0 {
tpl, err = template.New("text").Funcs(ctx.tplFuncMap()).Parse(job.Template)
} else {
// 先动态解析 TemplatePath
tplFile := ctx.MustEval(job.TemplatePath)
if !filepath.IsAbs(tplFile) && !strings.HasPrefix(tplFile, g.params["templatePath"]) {
tplFile = filepath.Join(g.params["templatePath"], tplFile)
}
tpl, err = template.New(filepath.Base(tplFile)).Funcs(ctx.tplFuncMap()).ParseFiles(tplFile)
}
g.FatalOnErr(err, "parse template: job: %s", job.Name)
// 渲染模板
writer := bytes.NewBuffer(nil)
err = tpl.Execute(writer, ctx.Data())
g.FatalOnErr(err, "execute template. job: %s object: %s", job.Name, ctx.Message().GetName())
ctx.SetContent(writer.Bytes())
// 调用插件:处理生成的内容
ctx.callPlugins(func(plugin Plugin) {
plugin.BeforeOut(ctx)
})
content := ctx.Content()
// 输出
err = g.WriteOutFile(outFileName, content)
g.FatalOnErr(err, "write out file failed. job(%s) job.out(%s)(parsed:%s)",
job.Name, job.Out, outFileName)
}
func (g *Generator) getJobs(ctx *Context) []Job {
jobs := make([]Job, 0)
for _, job := range g.conf.Jobs {
if !job.IsEnable(ctx) {
continue
}
jobs = append(jobs, job)
}
return jobs
}