You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
3.9 KiB
143 lines
3.9 KiB
package genbm |
|
|
|
import ( |
|
"fmt" |
|
"io" |
|
|
|
"go-common/app/tool/protoc-gen-bm/util" |
|
) |
|
|
|
const ( |
|
bmPkgPath = "go-common/library/net/http/blademaster" |
|
) |
|
|
|
// BMGenerate generate bm server code |
|
type BMGenerate struct { |
|
target io.Writer |
|
packageName string |
|
descs []*BMServerDescriptor |
|
err error |
|
jsonpb bool |
|
} |
|
|
|
// NewBMGenerate BMGenerate |
|
func NewBMGenerate(packageName string, descs []*BMServerDescriptor, jsonpb bool) *BMGenerate { |
|
return &BMGenerate{ |
|
packageName: packageName, |
|
descs: descs, |
|
jsonpb: jsonpb, |
|
} |
|
} |
|
|
|
// Generate code |
|
func (b *BMGenerate) Generate(target io.Writer) error { |
|
b.target = target |
|
methodsCount := 0 |
|
for _, desc := range b.descs { |
|
methodsCount += len(desc.Methods) |
|
} |
|
// if not methods found, can't generate anything |
|
if methodsCount == 0 { |
|
return nil |
|
} |
|
b.generatePackageImport() |
|
for _, desc := range b.descs { |
|
b.generateServer(desc) |
|
} |
|
return b.err |
|
} |
|
|
|
// P print code |
|
func (b *BMGenerate) P(args ...interface{}) { |
|
if b.err != nil { |
|
return |
|
} |
|
args = append(args, "\n") |
|
_, b.err = fmt.Fprint(b.target, args...) |
|
} |
|
|
|
func (b *BMGenerate) generatePackageImport() { |
|
b.P("// Package ", b.packageName, " Code generated by go-common/app/tool/protoc-gen-bm. DO NOT EDIT.") |
|
b.P("package ", b.packageName) |
|
b.P() |
|
b.P("import (") |
|
b.P(" \"context\"") |
|
if b.jsonpb { |
|
b.P(" \"bytes\"") |
|
b.P(" \"encoding/json\"") |
|
b.P() |
|
b.P(" \"go-common/app/tool/protoc-gen-bm/jsonpb\"") |
|
} |
|
b.P() |
|
b.P(" bm \"", bmPkgPath, "\"") |
|
b.P(")") |
|
b.P() |
|
} |
|
|
|
func (b *BMGenerate) generateServer(desc *BMServerDescriptor) { |
|
b.generateServerInterface(desc) |
|
b.generateServerHandler(desc) |
|
b.generateRegisterFunc(desc) |
|
} |
|
|
|
func (b *BMGenerate) generateServerInterface(desc *BMServerDescriptor) { |
|
serviceName := util.CamelCase(desc.Name) |
|
b.P(fmt.Sprintf("// BM%sServer interface as same as gGRPC server define", serviceName)) |
|
b.P("type BM", serviceName, "Server interface {") |
|
for _, method := range desc.Methods { |
|
b.P(" ", util.CamelCase(method.Name), fmt.Sprintf("(context.Context, *%s) (*%s, error)", method.RequestType, method.ReplyType)) |
|
} |
|
b.P("}") |
|
b.P() |
|
} |
|
|
|
func (b *BMGenerate) generateServerHandler(desc *BMServerDescriptor) { |
|
serviceName := util.CamelCase(desc.Name) |
|
receiverName := fmt.Sprintf("_BMServer%s", serviceName) |
|
b.P("// _BMServer", serviceName, "server") |
|
b.P("type ", receiverName, " struct {") |
|
b.P(" BM", serviceName, "Server") |
|
b.P("}") |
|
b.P() |
|
for _, method := range desc.Methods { |
|
methodName := util.CamelCase(method.Name) |
|
funcName := fmt.Sprintf("bm%s%sHandler", serviceName, methodName) |
|
b.P(fmt.Sprintf("func (b *%s) ", receiverName), funcName, "(c *bm.Context) {") |
|
// bind req |
|
b.P(fmt.Sprintf(" req := new(%s)", method.RequestType)) |
|
b.P(fmt.Sprintf(" if err := c.Bind(req); err != nil {")) |
|
b.P(" return") |
|
b.P(" }") |
|
// call service |
|
b.P(fmt.Sprintf(" reply, err := b.%s(c.Context, req)", methodName)) |
|
if b.jsonpb { |
|
b.P(" if err != nil {") |
|
b.P(" c.JSON(nil, err)") |
|
b.P(" return") |
|
b.P(" }") |
|
b.P(" body := &bytes.Buffer{}") |
|
b.P(" marshaler := jsonpb.Marshaler{EmitDefaults: true, OrigName: true}") |
|
b.P(" err = marshaler.Marshal(body, reply)") |
|
b.P(" c.JSON(json.RawMessage(body.Bytes()), err)") |
|
} else { |
|
b.P(" c.JSON(reply, err)") |
|
} |
|
b.P("}") |
|
b.P() |
|
} |
|
} |
|
|
|
func (b *BMGenerate) generateRegisterFunc(desc *BMServerDescriptor) { |
|
serviceName := util.CamelCase(desc.Name) |
|
receiverName := fmt.Sprintf("_BMServer%s", serviceName) |
|
b.P(fmt.Sprintf("// Register%sBMServer register bm server", serviceName)) |
|
b.P(fmt.Sprintf("func Register%sBMServer(e *bm.Engine, s BM%sServer) {", serviceName, serviceName)) |
|
b.P(fmt.Sprintf(" bs := &%s{s}", receiverName)) |
|
for _, method := range desc.Methods { |
|
methodName := util.CamelCase(method.Name) |
|
funcName := fmt.Sprintf("bm%s%sHandler", serviceName, methodName) |
|
b.P(fmt.Sprintf(" e.%s(\"%s\", bs.%s)", method.Method, method.PathPattern, funcName)) |
|
} |
|
b.P("}") |
|
b.P() |
|
}
|
|
|