Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
f22d8ed055 | |||
3806fb9336 | |||
a0385eff9c | |||
0f957b897b | |||
9bad6b85f3 | |||
9cc9e19e0b |
7
http.go
7
http.go
@@ -38,14 +38,15 @@ func (g *Generator) httpGenerate(component string, plugin *protogen.Plugin, genC
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, service := range file.Services {
|
for _, service := range file.Services {
|
||||||
|
g.generateServiceEndpoints(gfile, service, component)
|
||||||
if genClient {
|
if genClient {
|
||||||
g.generateServiceClient(gfile, service)
|
g.generateServiceClient(gfile, file, service)
|
||||||
g.generateServiceClientMethods(gfile, service, component)
|
g.generateServiceClientMethods(gfile, service, component)
|
||||||
}
|
}
|
||||||
if genServer {
|
if genServer {
|
||||||
generateServiceServer(gfile, service)
|
g.generateServiceServer(gfile, file, service)
|
||||||
g.generateServiceServerMethods(gfile, service)
|
g.generateServiceServerMethods(gfile, service)
|
||||||
g.generateServiceRegister(gfile, service, component)
|
g.generateServiceRegister(gfile, file, service, component)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
main.go
7
main.go
@@ -63,8 +63,8 @@ func (g *Generator) Generate(plugin *protogen.Plugin) error {
|
|||||||
g.reflection = *flagReflection
|
g.reflection = *flagReflection
|
||||||
plugin.SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL)
|
plugin.SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL)
|
||||||
|
|
||||||
var genClient bool
|
genClient := true
|
||||||
var genServer bool
|
genServer := true
|
||||||
var genNone bool
|
var genNone bool
|
||||||
|
|
||||||
if strings.Contains(g.components, "server") {
|
if strings.Contains(g.components, "server") {
|
||||||
@@ -90,6 +90,9 @@ func (g *Generator) Generate(plugin *protogen.Plugin) error {
|
|||||||
continue
|
continue
|
||||||
case "micro":
|
case "micro":
|
||||||
err = g.microGenerate(component, plugin, genClient, genServer)
|
err = g.microGenerate(component, plugin, genClient, genServer)
|
||||||
|
if err == nil {
|
||||||
|
err = g.writeErrors(plugin)
|
||||||
|
}
|
||||||
case "http":
|
case "http":
|
||||||
err = g.httpGenerate(component, plugin, genClient, genServer)
|
err = g.httpGenerate(component, plugin, genClient, genServer)
|
||||||
case "grpc", "drpc", "rpc":
|
case "grpc", "drpc", "rpc":
|
||||||
|
1
micro.go
1
micro.go
@@ -40,7 +40,6 @@ func (g *Generator) microGenerate(component string, plugin *protogen.Plugin, gen
|
|||||||
// generate services
|
// generate services
|
||||||
for _, service := range file.Services {
|
for _, service := range file.Services {
|
||||||
g.generateServiceName(gfile, service)
|
g.generateServiceName(gfile, service)
|
||||||
g.generateServiceEndpoints(gfile, service, component)
|
|
||||||
if genClient {
|
if genClient {
|
||||||
g.generateServiceClientInterface(gfile, service)
|
g.generateServiceClientInterface(gfile, service)
|
||||||
g.generateServiceClientStreamInterface(gfile, service)
|
g.generateServiceClientStreamInterface(gfile, service)
|
||||||
|
6
rpc.go
6
rpc.go
@@ -37,13 +37,13 @@ func (g *Generator) rpcGenerate(component string, plugin *protogen.Plugin, genCl
|
|||||||
}
|
}
|
||||||
for _, service := range file.Services {
|
for _, service := range file.Services {
|
||||||
if genClient {
|
if genClient {
|
||||||
g.generateServiceClient(gfile, service)
|
g.generateServiceClient(gfile, file, service)
|
||||||
g.generateServiceClientMethods(gfile, service, component)
|
g.generateServiceClientMethods(gfile, service, component)
|
||||||
}
|
}
|
||||||
if genServer {
|
if genServer {
|
||||||
generateServiceServer(gfile, service)
|
g.generateServiceServer(gfile, file, service)
|
||||||
g.generateServiceServerMethods(gfile, service)
|
g.generateServiceServerMethods(gfile, service)
|
||||||
g.generateServiceRegister(gfile, service, component)
|
g.generateServiceRegister(gfile, file, service, component)
|
||||||
}
|
}
|
||||||
if component == "grpc" && g.reflection {
|
if component == "grpc" && g.reflection {
|
||||||
g.generateServiceDesc(gfile, file, service)
|
g.generateServiceDesc(gfile, file, service)
|
||||||
|
169
util.go
169
util.go
@@ -31,7 +31,7 @@ func unexport(s string) string {
|
|||||||
return strings.ToLower(s[:1]) + s[1:]
|
return strings.ToLower(s[:1]) + s[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Generator) generateServiceClient(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
func (g *Generator) generateServiceClient(gfile *protogen.GeneratedFile, file *protogen.File, service *protogen.Service) {
|
||||||
serviceName := service.GoName
|
serviceName := service.GoName
|
||||||
// if rule, ok := getMicroApiService(service); ok {
|
// if rule, ok := getMicroApiService(service); ok {
|
||||||
// gfile.P("// client wrappers ", strings.Join(rule.ClientWrappers, ", "))
|
// gfile.P("// client wrappers ", strings.Join(rule.ClientWrappers, ", "))
|
||||||
@@ -41,7 +41,11 @@ func (g *Generator) generateServiceClient(gfile *protogen.GeneratedFile, service
|
|||||||
gfile.P("name string")
|
gfile.P("name string")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
|
|
||||||
gfile.P("func New", serviceName, "Client(name string, c ", microClientPackage.Ident("Client"), ") ", serviceName, "Client {")
|
if g.standalone {
|
||||||
|
gfile.P("func New", serviceName, "Client(name string, c ", microClientPackage.Ident("Client"), ") ", file.GoImportPath.Ident(serviceName), "Client {")
|
||||||
|
} else {
|
||||||
|
gfile.P("func New", serviceName, "Client(name string, c ", microClientPackage.Ident("Client"), ") ", serviceName, "Client {")
|
||||||
|
}
|
||||||
gfile.P("return &", unexport(serviceName), "Client{c: c, name: name}")
|
gfile.P("return &", unexport(serviceName), "Client{c: c, name: name}")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
@@ -319,10 +323,14 @@ func (g *Generator) generateServiceClientMethods(gfile *protogen.GeneratedFile,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateServiceServer(gfile *protogen.GeneratedFile, service *protogen.Service) {
|
func (g *Generator) generateServiceServer(gfile *protogen.GeneratedFile, file *protogen.File, service *protogen.Service) {
|
||||||
serviceName := service.GoName
|
serviceName := service.GoName
|
||||||
gfile.P("type ", unexport(serviceName), "Server struct {")
|
gfile.P("type ", unexport(serviceName), "Server struct {")
|
||||||
gfile.P(serviceName, "Server")
|
if g.standalone {
|
||||||
|
gfile.P(file.GoImportPath.Ident(serviceName), "Server")
|
||||||
|
} else {
|
||||||
|
gfile.P(serviceName, "Server")
|
||||||
|
}
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P()
|
gfile.P()
|
||||||
}
|
}
|
||||||
@@ -477,9 +485,13 @@ func (g *Generator) generateServiceServerMethods(gfile *protogen.GeneratedFile,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Generator) generateServiceRegister(gfile *protogen.GeneratedFile, service *protogen.Service, component string) {
|
func (g *Generator) generateServiceRegister(gfile *protogen.GeneratedFile, file *protogen.File, service *protogen.Service, component string) {
|
||||||
serviceName := service.GoName
|
serviceName := service.GoName
|
||||||
gfile.P("func Register", serviceName, "Server(s ", microServerPackage.Ident("Server"), ", sh ", serviceName, "Server, opts ...", microServerPackage.Ident("HandlerOption"), ") error {")
|
if g.standalone {
|
||||||
|
gfile.P("func Register", serviceName, "Server(s ", microServerPackage.Ident("Server"), ", sh ", file.GoImportPath.Ident(serviceName), "Server, opts ...", microServerPackage.Ident("HandlerOption"), ") error {")
|
||||||
|
} else {
|
||||||
|
gfile.P("func Register", serviceName, "Server(s ", microServerPackage.Ident("Server"), ", sh ", serviceName, "Server, opts ...", microServerPackage.Ident("HandlerOption"), ") error {")
|
||||||
|
}
|
||||||
gfile.P("type ", unexport(serviceName), " interface {")
|
gfile.P("type ", unexport(serviceName), " interface {")
|
||||||
for _, method := range service.Methods {
|
for _, method := range service.Methods {
|
||||||
generateServerSignature(gfile, serviceName, method, true)
|
generateServerSignature(gfile, serviceName, method, true)
|
||||||
@@ -491,7 +503,11 @@ func (g *Generator) generateServiceRegister(gfile *protogen.GeneratedFile, servi
|
|||||||
gfile.P("h := &", unexport(serviceName), "Server{sh}")
|
gfile.P("h := &", unexport(serviceName), "Server{sh}")
|
||||||
gfile.P("var nopts []", microServerPackage.Ident("HandlerOption"))
|
gfile.P("var nopts []", microServerPackage.Ident("HandlerOption"))
|
||||||
if component == "http" {
|
if component == "http" {
|
||||||
|
// if g.standalone {
|
||||||
|
// gfile.P("nopts = append(nopts, ", microServerHttpPackage.Ident("HandlerEndpoints"), "(", file.GoImportPath.Ident(serviceName), "ServerEndpoints))")
|
||||||
|
// } else {
|
||||||
gfile.P("nopts = append(nopts, ", microServerHttpPackage.Ident("HandlerEndpoints"), "(", serviceName, "ServerEndpoints))")
|
gfile.P("nopts = append(nopts, ", microServerHttpPackage.Ident("HandlerEndpoints"), "(", serviceName, "ServerEndpoints))")
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
gfile.P("return s.Handle(s.NewHandler(&", serviceName, "{h}, append(nopts, opts...)...))")
|
gfile.P("return s.Handle(s.NewHandler(&", serviceName, "{h}, append(nopts, opts...)...))")
|
||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
@@ -776,6 +792,35 @@ func (g *Generator) getGoIdentByXref(xref string) (protogen.GoIdent, error) {
|
|||||||
return protogen.GoIdent{}, fmt.Errorf("not found")
|
return protogen.GoIdent{}, fmt.Errorf("not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *Generator) getMessageByXref(xref string) (*protogen.Message, error) {
|
||||||
|
idx := strings.LastIndex(xref, ".")
|
||||||
|
pkg := xref[:idx]
|
||||||
|
msg := xref[idx+1:]
|
||||||
|
for _, file := range g.plugin.Files {
|
||||||
|
if strings.Compare(pkg, *(file.Proto.Package)) != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if pmsg, err := getProtoMessage(file.Messages, msg); err == nil {
|
||||||
|
return pmsg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProtoMessage(messages []*protogen.Message, msg string) (*protogen.Message, error) {
|
||||||
|
for _, message := range messages {
|
||||||
|
if strings.Compare(msg, message.GoIdent.GoName) == 0 {
|
||||||
|
return message, nil
|
||||||
|
}
|
||||||
|
if len(message.Messages) > 0 {
|
||||||
|
if pmsg, err := getProtoMessage(message.Messages, msg); err == nil {
|
||||||
|
return pmsg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("not found")
|
||||||
|
}
|
||||||
|
|
||||||
func getGoIdentByMessage(messages []*protogen.Message, msg string) (protogen.GoIdent, error) {
|
func getGoIdentByMessage(messages []*protogen.Message, msg string) (protogen.GoIdent, error) {
|
||||||
for _, message := range messages {
|
for _, message := range messages {
|
||||||
if strings.Compare(msg, message.GoIdent.GoName) == 0 {
|
if strings.Compare(msg, message.GoIdent.GoName) == 0 {
|
||||||
@@ -868,3 +913,115 @@ func (g *Generator) generateServiceEndpoints(gfile *protogen.GeneratedFile, serv
|
|||||||
gfile.P("}")
|
gfile.P("}")
|
||||||
gfile.P(")")
|
gfile.P(")")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *Generator) writeErrors(plugin *protogen.Plugin) error {
|
||||||
|
errorsMap := make(map[string]struct{})
|
||||||
|
|
||||||
|
for _, file := range plugin.Files {
|
||||||
|
for _, service := range file.Services {
|
||||||
|
for _, method := range service.Methods {
|
||||||
|
if method.Desc.Options() != nil {
|
||||||
|
if proto.HasExtension(method.Desc.Options(), v2.E_Openapiv2Operation) {
|
||||||
|
opts := proto.GetExtension(method.Desc.Options(), v2.E_Openapiv2Operation)
|
||||||
|
if opts != nil {
|
||||||
|
r := opts.(*v2.Operation)
|
||||||
|
if r.Responses == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, rsp := range r.Responses.ResponseCode {
|
||||||
|
if schema := rsp.Value.GetJsonReference(); schema != nil {
|
||||||
|
xref := schema.XRef
|
||||||
|
if xref[0] == '.' {
|
||||||
|
xref = xref[1:]
|
||||||
|
}
|
||||||
|
errorsMap[xref] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if proto.HasExtension(method.Desc.Options(), v3.E_Openapiv3Operation) {
|
||||||
|
opts := proto.GetExtension(method.Desc.Options(), v3.E_Openapiv3Operation)
|
||||||
|
if opts != nil {
|
||||||
|
r := opts.(*v3.Operation)
|
||||||
|
if r.Responses == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
resps := r.Responses.ResponseOrReference
|
||||||
|
if r.Responses.GetDefault() != nil {
|
||||||
|
resps = append(resps, &v3.NamedResponseOrReference{Name: "default", Value: r.Responses.GetDefault()})
|
||||||
|
}
|
||||||
|
for _, rsp := range resps {
|
||||||
|
if schema := rsp.Value.GetReference(); schema != nil {
|
||||||
|
xref := schema.XRef
|
||||||
|
if xref[0] == '.' {
|
||||||
|
xref = xref[1:]
|
||||||
|
}
|
||||||
|
errorsMap[xref] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var gfile *protogen.GeneratedFile
|
||||||
|
var importPath protogen.GoImportPath
|
||||||
|
|
||||||
|
if len(errorsMap) > 0 {
|
||||||
|
|
||||||
|
var packageName string
|
||||||
|
|
||||||
|
for _, file := range plugin.Files {
|
||||||
|
if !file.Generate {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(file.Services) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
packageName = string(file.GoPackageName)
|
||||||
|
importPath = file.GoImportPath
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if g.standalone {
|
||||||
|
importPath = "."
|
||||||
|
}
|
||||||
|
|
||||||
|
gfile = plugin.NewGeneratedFile("micro_errors.pb.go", importPath)
|
||||||
|
|
||||||
|
gfile.P("// Code generated by protoc-gen-go-micro. DO NOT EDIT.")
|
||||||
|
gfile.P("// protoc-gen-go-micro version: " + versionComment)
|
||||||
|
gfile.P()
|
||||||
|
gfile.P("package ", packageName)
|
||||||
|
gfile.P()
|
||||||
|
|
||||||
|
gfile.Import(protojsonPackage)
|
||||||
|
|
||||||
|
gfile.P("var (")
|
||||||
|
gfile.P("marshaler = ", protojsonPackage.Ident("MarshalOptions"), "{}")
|
||||||
|
gfile.P(")")
|
||||||
|
}
|
||||||
|
|
||||||
|
for xref := range errorsMap {
|
||||||
|
msg, err := g.getMessageByXref(xref)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, field := range msg.Fields {
|
||||||
|
if field.GoName == "Error" {
|
||||||
|
return fmt.Errorf("failed generate Error() string interface for %s message %s already have Error field", field.Location.SourceFile, msg.Desc.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gfile.P(`func (m *`, msg.GoIdent.GoName, `) Error() string {`)
|
||||||
|
gfile.P(`buf, _ := marshaler.Marshal(m)`)
|
||||||
|
gfile.P("return string(buf)")
|
||||||
|
gfile.P(`}`)
|
||||||
|
// log.Printf("xref %#+v %v\n", msg.GoIdent.GoName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@@ -19,6 +19,7 @@ var (
|
|||||||
microCodecPackage = protogen.GoImportPath("go.unistack.org/micro-proto/v3/codec")
|
microCodecPackage = protogen.GoImportPath("go.unistack.org/micro-proto/v3/codec")
|
||||||
microErrorsPackage = protogen.GoImportPath("go.unistack.org/micro/v3/errors")
|
microErrorsPackage = protogen.GoImportPath("go.unistack.org/micro/v3/errors")
|
||||||
grpcPackage = protogen.GoImportPath("google.golang.org/grpc")
|
grpcPackage = protogen.GoImportPath("google.golang.org/grpc")
|
||||||
|
protojsonPackage = protogen.GoImportPath("google.golang.org/protobuf/encoding/protojson")
|
||||||
timePackage = protogen.GoImportPath("time")
|
timePackage = protogen.GoImportPath("time")
|
||||||
deprecationComment = "// Deprecated: Do not use."
|
deprecationComment = "// Deprecated: Do not use."
|
||||||
versionComment = "v3.10.4"
|
versionComment = "v3.10.4"
|
||||||
|
Reference in New Issue
Block a user