forked from grpc-ecosystem/grpc-gateway
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
146 lines (124 loc) · 5.2 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Command protoc-gen-grpc-gateway is a plugin for Google protocol buffer
// compiler to generate a reverse-proxy, which converts incoming RESTful
// HTTP/1 requests gRPC invocation.
// You rarely need to run this program directly. Instead, put this program
// into your $PATH with a name "protoc-gen-grpc-gateway" and run
// protoc --grpc-gateway_out=output_directory path/to/input.proto
//
// See README.md for more details.
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/golang/glog"
"github.com/grpc-ecosystem/grpc-gateway/v2/internal/codegenerator"
"github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
"github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway/internal/gengateway"
"google.golang.org/protobuf/compiler/protogen"
)
var (
registerFuncSuffix = flag.String("register_func_suffix", "Handler", "used to construct names of generated Register*<Suffix> methods.")
useRequestContext = flag.Bool("request_context", true, "determine whether to use http.Request's context or not")
allowDeleteBody = flag.Bool("allow_delete_body", false, "unless set, HTTP DELETE methods may not have a body")
grpcAPIConfiguration = flag.String("grpc_api_configuration", "", "path to gRPC API Configuration in YAML format")
allowRepeatedFieldsInBody = flag.Bool("allow_repeated_fields_in_body", false, "allows to use repeated field in `body` and `response_body` field of `google.api.http` annotation option")
repeatedPathParamSeparator = flag.String("repeated_path_param_separator", "csv", "configures how repeated fields should be split. Allowed values are `csv`, `pipes`, `ssv` and `tsv`.")
allowPatchFeature = flag.Bool("allow_patch_feature", true, "determines whether to use PATCH feature involving update masks (using google.protobuf.FieldMask).")
omitPackageDoc = flag.Bool("omit_package_doc", false, "if true, no package comment will be included in the generated code")
standalone = flag.Bool("standalone", false, "generates a standalone gateway package, which imports the target service package")
versionFlag = flag.Bool("version", false, "print the current version")
warnOnUnboundMethods = flag.Bool("warn_on_unbound_methods", false, "emit a warning message if an RPC method has no HttpRule annotation")
generateUnboundMethods = flag.Bool("generate_unbound_methods", false, "generate proxy methods even for RPC methods that have no HttpRule annotation")
)
// Variables set by goreleaser at build time
var (
version = "dev"
commit = "unknown"
date = "unknown"
)
func main() {
flag.Parse()
defer glog.Flush()
if *versionFlag {
fmt.Printf("Version %v, commit %v, built at %v\n", version, commit, date)
os.Exit(0)
}
protogen.Options{
ParamFunc: flag.CommandLine.Set,
}.Run(func(gen *protogen.Plugin) error {
reg := descriptor.NewRegistry()
err := applyFlags(reg)
if err != nil {
return err
}
codegenerator.SetSupportedFeaturesOnPluginGen(gen)
generator := gengateway.New(reg, *useRequestContext, *registerFuncSuffix, *allowPatchFeature, *standalone)
glog.V(1).Infof("Parsing code generator request")
if err := reg.LoadFromPlugin(gen); err != nil {
return err
}
unboundHTTPRules := reg.UnboundExternalHTTPRules()
if len(unboundHTTPRules) != 0 {
return fmt.Errorf("HTTP rules without a matching selector: %s", strings.Join(unboundHTTPRules, ", "))
}
var targets []*descriptor.File
for _, target := range gen.Request.FileToGenerate {
f, err := reg.LookupFile(target)
if err != nil {
return err
}
targets = append(targets, f)
}
files, err := generator.Generate(targets)
for _, f := range files {
glog.V(1).Infof("NewGeneratedFile %q in %s", f.GetName(), f.GoPkg)
genFile := gen.NewGeneratedFile(f.GetName(), protogen.GoImportPath(f.GoPkg.Path))
if _, err := genFile.Write([]byte(f.GetContent())); err != nil {
return err
}
}
glog.V(1).Info("Processed code generator request")
return err
})
}
func parseFlags(reg *descriptor.Registry, parameter string) {
if parameter == "" {
return
}
for _, p := range strings.Split(parameter, ",") {
spec := strings.SplitN(p, "=", 2)
if len(spec) == 1 {
if err := flag.CommandLine.Set(spec[0], ""); err != nil {
glog.Fatalf("Cannot set flag %s", p)
}
continue
}
name, value := spec[0], spec[1]
if strings.HasPrefix(name, "M") {
reg.AddPkgMap(name[1:], value)
continue
}
if err := flag.CommandLine.Set(name, value); err != nil {
glog.Fatalf("Cannot set flag %s", p)
}
}
}
func applyFlags(reg *descriptor.Registry) error {
if *grpcAPIConfiguration != "" {
if err := reg.LoadGrpcAPIServiceFromYAML(*grpcAPIConfiguration); err != nil {
return err
}
}
if *warnOnUnboundMethods && *generateUnboundMethods {
glog.Warningf("Option warn_on_unbound_methods has no effect when generate_unbound_methods is used.")
}
reg.SetStandalone(*standalone)
reg.SetAllowDeleteBody(*allowDeleteBody)
reg.SetAllowRepeatedFieldsInBody(*allowRepeatedFieldsInBody)
reg.SetOmitPackageDoc(*omitPackageDoc)
reg.SetWarnOnUnboundMethods(*warnOnUnboundMethods)
reg.SetGenerateUnboundMethods(*generateUnboundMethods)
return reg.SetRepeatedPathParamSeparator(*repeatedPathParamSeparator)
}