github.com/unionj-cloud/go-doudou@v1.3.8-0.20221011095552-0088008e5b31/cmd/internal/protobuf/v3/service.go (about) 1 package v3 2 3 import ( 4 "fmt" 5 "github.com/iancoleman/strcase" 6 "github.com/unionj-cloud/go-doudou/cmd/internal/astutils" 7 "github.com/unionj-cloud/go-doudou/toolkit/constants" 8 "github.com/unionj-cloud/go-doudou/version" 9 "reflect" 10 "strings" 11 "time" 12 ) 13 14 // service SearchService { 15 // rpc Search(SearchRequest) returns (SearchResponse); 16 // } 17 18 const Syntax = "proto3" 19 20 type Service struct { 21 Name string 22 Package string 23 GoPackage string 24 Syntax string 25 // go-doudou version 26 Version string 27 ProtoVer string 28 Rpcs []Rpc 29 Messages []Message 30 Enums []Enum 31 Comments []string 32 Imports []string 33 } 34 35 func NewService(name, goPackage string) Service { 36 return Service{ 37 Name: strcase.ToCamel(name) + "Service", 38 Package: strcase.ToSnake(name), 39 GoPackage: goPackage, 40 Syntax: Syntax, 41 Version: version.Release, 42 ProtoVer: fmt.Sprintf("v%s", time.Now().Local().Format(constants.FORMAT10)), 43 } 44 } 45 46 type StreamType int 47 48 const ( 49 biStream = iota + 1 50 clientStream 51 serverStream 52 ) 53 54 type Rpc struct { 55 Name string 56 Request Message 57 Response Message 58 Comments []string 59 StreamType StreamType 60 } 61 62 func NewRpc(method astutils.MethodMeta) Rpc { 63 rpcName := strcase.ToCamel(method.Name) + "Rpc" 64 rpcRequest := newRequest(rpcName, method.Params) 65 if reflect.DeepEqual(rpcRequest, Empty) { 66 ImportStore["google/protobuf/empty.proto"] = struct{}{} 67 } 68 if !strings.HasPrefix(rpcRequest.Name, "stream ") { 69 if _, ok := MessageStore[rpcRequest.Name]; !ok { 70 MessageStore[rpcRequest.Name] = rpcRequest 71 } 72 } 73 rpcResponse := newResponse(rpcName, method.Results) 74 if reflect.DeepEqual(rpcResponse, Empty) { 75 ImportStore["google/protobuf/empty.proto"] = struct{}{} 76 } 77 if !strings.HasPrefix(rpcResponse.Name, "stream ") { 78 if _, ok := MessageStore[rpcResponse.Name]; !ok { 79 MessageStore[rpcResponse.Name] = rpcResponse 80 } 81 } 82 var st StreamType 83 if strings.HasPrefix(rpcRequest.Name, "stream ") && strings.HasPrefix(rpcResponse.Name, "stream ") { 84 st = biStream 85 } else if strings.HasPrefix(rpcRequest.Name, "stream ") { 86 st = clientStream 87 } else if strings.HasPrefix(rpcResponse.Name, "stream ") { 88 st = serverStream 89 } 90 return Rpc{ 91 Name: rpcName, 92 Request: rpcRequest, 93 Response: rpcResponse, 94 Comments: method.Comments, 95 StreamType: st, 96 } 97 } 98 99 func newRequest(rpcName string, params []astutils.FieldMeta) Message { 100 if len(params) == 0 { 101 return Empty 102 } 103 if len(params) == 1 && params[0].Type == "context.Context" { 104 return Empty 105 } 106 if params[0].Type == "context.Context" { 107 params = params[1:] 108 } 109 if len(params) == 1 { 110 if m, ok := MessageOf(params[0].Type).(Message); ok && m.IsTopLevel { 111 if strings.HasPrefix(params[0].Name, "stream") { 112 m.Name = "stream " + m.Name 113 } 114 return m 115 } 116 } 117 var fields []Field 118 for i, field := range params { 119 fields = append(fields, newField(field, i+1)) 120 } 121 return Message{ 122 Name: strcase.ToCamel(rpcName + "Request"), 123 Fields: fields, 124 IsTopLevel: true, 125 } 126 } 127 128 func newResponse(rpcName string, params []astutils.FieldMeta) Message { 129 if len(params) == 0 { 130 return Empty 131 } 132 if len(params) == 1 && params[0].Type == "error" { 133 return Empty 134 } 135 if params[len(params)-1].Type == "error" { 136 params = params[:len(params)-1] 137 } 138 if len(params) == 1 { 139 if m, ok := MessageOf(params[0].Type).(Message); ok && m.IsTopLevel { 140 if strings.HasPrefix(params[0].Name, "stream") { 141 m.Name = "stream " + m.Name 142 } 143 return m 144 } 145 } 146 var fields []Field 147 for i, field := range params { 148 fields = append(fields, newField(field, i+1)) 149 } 150 return Message{ 151 Name: strcase.ToCamel(rpcName + "Response"), 152 Fields: fields, 153 IsTopLevel: true, 154 } 155 }