forked from layotto/protoc-gen-p6
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
121 lines (101 loc) · 3.28 KB
/
main.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 main
import (
"flag"
"fmt"
mode "github.com/layotto/protoc-gen-p6/mode"
"github.com/layotto/protoc-gen-p6/render/api"
"github.com/layotto/protoc-gen-p6/render/client"
"github.com/layotto/protoc-gen-p6/render/genstruct"
"github.com/layotto/protoc-gen-p6/render/gentemplate"
"github.com/layotto/protoc-gen-p6/render/runtime"
"github.com/layotto/protoc-gen-p6/utils"
"google.golang.org/protobuf/compiler/protogen"
"google.golang.org/protobuf/types/pluginpb"
)
const version = "0.0.1"
func main() {
// check version flag
showVersion := flag.Bool("version", false, "show version")
flag.Parse()
if *showVersion {
fmt.Printf("protoc-gen-p6 %v\n", version)
return
}
// render
var flags flag.FlagSet
options := protogen.Options{
ParamFunc: flags.Set,
}
options.Run(func(gen *protogen.Plugin) error {
gen.SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL)
components := make([]*protogen.File, 0)
apis := make([]*protogen.File, 0)
needSDK := make([]*protogen.File, 0)
sdkRender := client.NewRender(gen)
for _, f := range gen.Files {
if !f.Generate {
continue
}
// 1. generate components code
// 1.1. generate struct
_, name := utils.SplitDirectoryAndFilename(f.GeneratedFilenamePrefix)
dir := "components/" + name + "/"
filename := dir + "/struct_generated.go"
genstruct.GenerateStructFile(gen, f, filename)
// 1.2. generate code for grpc service
// check if there is any service
if len(f.Services) == 0 {
continue
}
// Note: we allow only 1 service in a file
if len(f.Services) > 1 {
panic("There are more than one service in a file.")
}
// check mode
comments := make([]string, 0)
for _, comment := range f.Services[0].Comments.LeadingDetached {
comments = append(comments, comment.String())
}
comments = append(comments, f.Services[0].Comments.Leading.String())
compileMode, args := mode.CheckMode(comments)
filename = dir + "/interface_generated.go"
if compileMode == mode.Independent {
// generate component interface
gentemplate.GenerateComponentInterface(gen, f, filename)
// generate types
filename = dir + "/types_generated.go"
gentemplate.GenerateComponentTypes(gen, f, filename)
components = append(components, f)
// generate gRPC API plugin code
gentemplate.GenerateAPI(gen, f)
} else if compileMode == mode.Extend {
// TODO multiple extends
// generate component interface
gentemplate.GenerateExtendComponentInterface(gen, f, filename)
// no need to generate types
// generate gRPC API plugin code
gentemplate.GenerateExtendAPI(gen, f, args[0])
}
// 2. collect api plugins
apis = append(apis, f)
if mode.NeedGenerateSDK(comments) {
needSDK = append(needSDK, f)
}
}
if len(components) > 0 {
// 3. generate ApplicationContext
api.GenerateApplicationContext(gen, components)
// 4. runtime related code
runtime.GenerateExtensionComponentConfig(gen, components)
runtime.GenerateOptions(gen, components)
runtime.GenerateNewApplicationContext(gen, components)
runtime.GenerateComponentRelatedCode(gen, components)
}
runtime.GenerateWithExtensionGrpcAPI(gen, apis)
// 5. generate golang sdk
if len(needSDK) > 0 {
return sdkRender.Render(needSDK)
}
return nil
})
}