github.com/cloudwego/kitex@v0.9.0/pkg/serviceinfo/serviceinfo.go (about) 1 /* 2 * Copyright 2021 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package serviceinfo 18 19 import ( 20 "context" 21 ) 22 23 // PayloadCodec alias type 24 type PayloadCodec int 25 26 // PayloadCodec supported by kitex. 27 const ( 28 Thrift PayloadCodec = iota 29 Protobuf 30 Hessian2 31 ) 32 33 const ( 34 // GenericService name 35 GenericService = "$GenericService" // private as "$" 36 // GenericMethod name 37 GenericMethod = "$GenericCall" 38 ) 39 40 // ServiceInfo to record meta info of service 41 type ServiceInfo struct { 42 // deprecated, for compatibility 43 PackageName string 44 45 // The name of the service. For generic services, it is always the constant `GenericService`. 46 ServiceName string 47 48 // HandlerType is the type value of a request handler from the generated code. 49 HandlerType interface{} 50 51 // Methods contains the meta information of methods supported by the service. 52 // For generic service, there is only one method named by the constant `GenericMethod`. 53 Methods map[string]MethodInfo 54 55 // PayloadCodec is the codec of payload. 56 PayloadCodec PayloadCodec 57 58 // KiteXGenVersion is the version of command line tool 'kitex'. 59 KiteXGenVersion string 60 61 // Extra is for future feature info, to avoid compatibility issue 62 // as otherwise we need to add a new field in the struct 63 Extra map[string]interface{} 64 65 // GenericMethod returns a MethodInfo for the given name. 66 // It is used by generic calls only. 67 GenericMethod func(name string) MethodInfo 68 } 69 70 // GetPackageName returns the PackageName. 71 // The return value is generally taken from the Extra field of ServiceInfo with a key 72 // `PackageName`. For some legacy generated code, it may come from the PackageName field. 73 func (i *ServiceInfo) GetPackageName() (pkg string) { 74 if i.PackageName != "" { 75 return i.PackageName 76 } 77 pkg, _ = i.Extra["PackageName"].(string) 78 return 79 } 80 81 // MethodInfo gets MethodInfo. 82 func (i *ServiceInfo) MethodInfo(name string) MethodInfo { 83 if i == nil { 84 return nil 85 } 86 if i.ServiceName == GenericService { 87 if i.GenericMethod != nil { 88 return i.GenericMethod(name) 89 } 90 return i.Methods[GenericMethod] 91 } 92 return i.Methods[name] 93 } 94 95 type StreamingMode int 96 97 const ( 98 StreamingNone StreamingMode = 0b0000 // KitexPB/KitexThrift 99 StreamingUnary StreamingMode = 0b0001 // underlying protocol for streaming, like HTTP2 100 StreamingClient StreamingMode = 0b0010 101 StreamingServer StreamingMode = 0b0100 102 StreamingBidirectional StreamingMode = 0b0110 103 ) 104 105 // MethodInfo to record meta info of unary method 106 type MethodInfo interface { 107 Handler() MethodHandler 108 NewArgs() interface{} 109 NewResult() interface{} 110 OneWay() bool 111 IsStreaming() bool 112 StreamingMode() StreamingMode 113 } 114 115 // MethodHandler is corresponding to the handler wrapper func that in generated code 116 type MethodHandler func(ctx context.Context, handler, args, result interface{}) error 117 118 // MethodInfoOption modifies the given MethodInfo 119 type MethodInfoOption func(*methodInfo) 120 121 // WithStreamingMode sets the streaming mode and update the streaming flag accordingly 122 func WithStreamingMode(mode StreamingMode) MethodInfoOption { 123 return func(m *methodInfo) { 124 m.streamingMode = mode 125 m.isStreaming = mode != StreamingNone 126 } 127 } 128 129 // NewMethodInfo is called in generated code to build method info 130 func NewMethodInfo(methodHandler MethodHandler, newArgsFunc, newResultFunc func() interface{}, oneWay bool, opts ...MethodInfoOption) MethodInfo { 131 mi := methodInfo{ 132 handler: methodHandler, 133 newArgsFunc: newArgsFunc, 134 newResultFunc: newResultFunc, 135 oneWay: oneWay, 136 isStreaming: false, 137 streamingMode: StreamingNone, 138 } 139 for _, opt := range opts { 140 opt(&mi) 141 } 142 return &mi 143 } 144 145 type methodInfo struct { 146 handler MethodHandler 147 newArgsFunc func() interface{} 148 newResultFunc func() interface{} 149 oneWay bool 150 isStreaming bool 151 streamingMode StreamingMode 152 } 153 154 // Handler implements the MethodInfo interface. 155 func (m methodInfo) Handler() MethodHandler { 156 return m.handler 157 } 158 159 // NewArgs implements the MethodInfo interface. 160 func (m methodInfo) NewArgs() interface{} { 161 return m.newArgsFunc() 162 } 163 164 // NewResult implements the MethodInfo interface. 165 func (m methodInfo) NewResult() interface{} { 166 return m.newResultFunc() 167 } 168 169 // OneWay implements the MethodInfo interface. 170 func (m methodInfo) OneWay() bool { 171 return m.oneWay 172 } 173 174 func (m methodInfo) IsStreaming() bool { 175 return m.isStreaming 176 } 177 178 func (m methodInfo) StreamingMode() StreamingMode { 179 return m.streamingMode 180 } 181 182 // String prints human-readable information. 183 func (p PayloadCodec) String() string { 184 switch p { 185 case Thrift: 186 return "Thrift" 187 case Protobuf: 188 return "Protobuf" 189 case Hessian2: 190 return "Hessian2" 191 } 192 panic("unknown payload type") 193 }