github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/thrift/descriptor.go (about) 1 /** 2 * Copyright 2023 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 thrift 18 19 import ( 20 "fmt" 21 22 "github.com/apache/thrift/lib/go/thrift" 23 "github.com/cloudwego/dynamicgo/http" 24 "github.com/cloudwego/thriftgo/parser" 25 ) 26 27 const ( 28 VERSION_MASK = 0xffff0000 29 VERSION_1 = 0x80010000 30 ) 31 32 // Type constants in the Thrift protocol 33 type Type byte 34 35 // built-in Types 36 const ( 37 STOP Type = 0 38 VOID Type = 1 39 BOOL Type = 2 40 BYTE Type = 3 41 I08 Type = 3 42 DOUBLE Type = 4 43 I16 Type = 6 44 I32 Type = 8 45 I64 Type = 10 46 STRING Type = 11 47 // UTF7 Type = 11 48 STRUCT Type = 12 49 MAP Type = 13 50 SET Type = 14 51 LIST Type = 15 52 UTF8 Type = 16 53 UTF16 Type = 17 54 // BINARY Type = 18 wrong and unusued 55 56 ERROR Type = 255 57 ) 58 59 func (p Type) Valid() bool { 60 switch p { 61 case STOP, VOID, BOOL, BYTE, DOUBLE, I16, I32, I64, STRING, STRUCT, MAP, SET, LIST, UTF8, UTF16: 62 return true 63 default: 64 return false 65 } 66 } 67 68 // String for format and print 69 func (p Type) String() string { 70 switch p { 71 case STOP: 72 return "STOP" 73 case VOID: 74 return "VOID" 75 case BOOL: 76 return "BOOL" 77 case BYTE: 78 return "BYTE" 79 case DOUBLE: 80 return "DOUBLE" 81 case I16: 82 return "I16" 83 case I32: 84 return "I32" 85 case I64: 86 return "I64" 87 case STRING: 88 return "STRING" 89 case STRUCT: 90 return "STRUCT" 91 case MAP: 92 return "MAP" 93 case SET: 94 return "SET" 95 case LIST: 96 return "LIST" 97 case UTF8: 98 return "UTF8" 99 case UTF16: 100 return "UTF16" 101 case ERROR: 102 return "ERROR" 103 } 104 return "Unknown" 105 } 106 107 // IsInt tells if the type is one of I08, I16, I32, I64 108 func (p Type) IsInt() bool { 109 return p == I08 || p == I16 || p == I32 || p == I64 110 } 111 112 // IsComplex tells if the type is one of STRUCT, MAP, SET, LIST 113 func (p Type) IsComplex() bool { 114 return p == STRUCT || p == MAP || p == SET || p == LIST 115 } 116 117 // ToThriftTType converts Type to apache/thrift.TType 118 func (p Type) ToThriftTType() thrift.TType { 119 return thrift.TType(p) 120 } 121 122 // FromThriftTType converts apache/thrift.TType to Type 123 func FromThriftTType(t thrift.TType) Type { 124 return Type(t) 125 } 126 127 // TypeDescriptor is the runtime descriptor of a thrift type 128 type TypeDescriptor struct { 129 typ Type 130 name string 131 key *TypeDescriptor // for map key 132 elem *TypeDescriptor // for slice or map element 133 struc *StructDescriptor // for struct 134 } 135 136 const ( 137 nameBinary = "binary" 138 ) 139 140 // IsBinary tells if the type is binary type ([]byte) 141 func (d TypeDescriptor) IsBinary() bool { 142 if d.name == nameBinary { 143 return true 144 } 145 return false 146 } 147 148 // Type returns the build-in type of the descriptor 149 func (d TypeDescriptor) Type() Type { 150 return d.typ 151 } 152 153 // Name returns the name of the descriptor 154 // 155 // for struct, it is the struct name; 156 // for build-in type, it is the type name. 157 func (d TypeDescriptor) Name() string { 158 return d.name 159 } 160 161 // Key returns the key type descriptor of a MAP type 162 func (d TypeDescriptor) Key() *TypeDescriptor { 163 return d.key 164 } 165 166 // Elem returns the element type descriptor of a LIST, SET or MAP type 167 func (d TypeDescriptor) Elem() *TypeDescriptor { 168 return d.elem 169 } 170 171 // Struct returns the struct type descriptor of a STRUCT type 172 func (d TypeDescriptor) Struct() *StructDescriptor { 173 return d.struc 174 } 175 176 // StructDescriptor is the runtime descriptor of a STRUCT type 177 type StructDescriptor struct { 178 baseID FieldID 179 name string 180 ids FieldIDMap 181 names FieldNameMap 182 requires RequiresBitmap 183 hmFields []*FieldDescriptor 184 annotations []parser.Annotation 185 } 186 187 // GetRequestBase returns the base.Base field of a STRUCT 188 func (s StructDescriptor) GetRequestBase() *FieldDescriptor { 189 field := s.FieldById(s.baseID) 190 if field != nil && field.IsRequestBase() { 191 return field 192 } 193 return nil 194 } 195 196 // GetResponseBase returns the base.BaseResp field of a STRUCT 197 func (s StructDescriptor) GetResponseBase() *FieldDescriptor { 198 field := s.FieldById(s.baseID) 199 if field != nil && field.IsResponseBase() { 200 return field 201 } 202 return nil 203 } 204 205 // GetHttpMappingFields returns the fields with http-mapping annotations 206 func (s StructDescriptor) HttpMappingFields() []*FieldDescriptor { 207 return s.hmFields 208 } 209 210 func (s *StructDescriptor) addHttpMappingField(f *FieldDescriptor) { 211 for _, fd := range s.hmFields { 212 if fd.id == f.id { 213 return 214 } 215 } 216 s.hmFields = append(s.hmFields, f) 217 } 218 219 // Name returns the name of the struct 220 func (s StructDescriptor) Name() string { 221 return s.name 222 } 223 224 // Len returns the number of fields in the struct 225 func (s StructDescriptor) Len() int { 226 return len(s.ids.all) 227 } 228 229 // Fields returns all fields in the struct 230 func (s StructDescriptor) Fields() []*FieldDescriptor { 231 return s.ids.All() 232 } 233 234 // Fields returns requireness bitmap in the struct. 235 // By default, only Requred and Default fields are marked. 236 func (s StructDescriptor) Requires() RequiresBitmap { 237 return s.requires 238 } 239 240 func (s StructDescriptor) Annotations() []parser.Annotation { 241 return s.annotations 242 } 243 244 // FieldById finds the field by field id 245 func (s StructDescriptor) FieldById(id FieldID) *FieldDescriptor { 246 return s.ids.Get(id) 247 } 248 249 // FieldByName finds the field by key 250 // 251 // NOTICE: Options.MapFieldWay can influence the behavior of this method. 252 // ep: if Options.MapFieldWay is MapFieldWayName, then field names should be used as key. 253 func (s StructDescriptor) FieldByKey(k string) (field *FieldDescriptor) { 254 return s.names.Get(k) 255 } 256 257 // FieldID is used to identify a field in a struct 258 type FieldID uint16 259 260 // FieldDescriptor is the runtime descriptor of a field in a struct 261 type FieldDescriptor struct { 262 // isException bool 263 isRequestBase bool 264 isResponseBase bool 265 required Requireness 266 valueMappingType AnnoType 267 id FieldID 268 typ *TypeDescriptor 269 defaultValue *DefaultValue 270 name string // field name 271 alias string // alias name 272 valueMapping ValueMapping 273 httpMappings []HttpMapping 274 annotations []parser.Annotation 275 } 276 277 // func (f FieldDescriptor) IsException() bool { 278 // return f.isException 279 // } 280 281 // IsRequestBase tells if the field is base.Base 282 func (f FieldDescriptor) IsRequestBase() bool { 283 return f.isRequestBase 284 } 285 286 // IsResponseBase tells if the field is base.BaseResp 287 func (f FieldDescriptor) IsResponseBase() bool { 288 return f.isResponseBase 289 } 290 291 // ValueMappingType returns the value-mapping annotation's type of a field 292 func (f FieldDescriptor) ValueMappingType() AnnoType { 293 return f.valueMappingType 294 } 295 296 // Required return the requiredness of a field 297 func (f FieldDescriptor) Required() Requireness { 298 return f.required 299 } 300 301 // ID returns the id of a field 302 func (f FieldDescriptor) ID() FieldID { 303 return f.id 304 } 305 306 // Name returns the name of a field 307 func (f FieldDescriptor) Name() string { 308 return f.name 309 } 310 311 // Alias returns the alias of a field 312 func (f FieldDescriptor) Alias() string { 313 return f.alias 314 } 315 316 // Type returns the type descriptor of a field 317 func (f FieldDescriptor) Type() *TypeDescriptor { 318 return f.typ 319 } 320 321 // HTTPMappings returns the http-mapping annotations of a field 322 func (f FieldDescriptor) HTTPMappings() []HttpMapping { 323 return f.httpMappings 324 } 325 326 // ValueMapping returns the value-mapping annotation of a field 327 func (f FieldDescriptor) ValueMapping() ValueMapping { 328 return f.valueMapping 329 } 330 331 func (f FieldDescriptor) Annotations() []parser.Annotation { 332 return f.annotations 333 } 334 335 // DefaultValue returns the default value of a field 336 func (f FieldDescriptor) DefaultValue() *DefaultValue { 337 return f.defaultValue 338 } 339 340 // FunctionDescriptor idl function descriptor 341 type FunctionDescriptor struct { 342 oneway bool 343 hasRequestBase bool 344 request *TypeDescriptor 345 response *TypeDescriptor 346 name string 347 endpoints []http.Endpoint 348 annotations []parser.Annotation 349 } 350 351 // Name returns the name of the function 352 func (f FunctionDescriptor) Name() string { 353 return f.name 354 } 355 356 // Oneway tells if the function is oneway type 357 func (f FunctionDescriptor) Oneway() bool { 358 return f.oneway 359 } 360 361 // HasRequestBase tells if the function has a base.Base field 362 func (f FunctionDescriptor) HasRequestBase() bool { 363 return f.hasRequestBase 364 } 365 366 // Request returns the request type descriptor of the function 367 // The request arguements is mapped with arguement id and name 368 func (f FunctionDescriptor) Request() *TypeDescriptor { 369 return f.request 370 } 371 372 // Response returns the response type descriptor of the function 373 // The response arguements is mapped with arguement id 374 func (f FunctionDescriptor) Response() *TypeDescriptor { 375 return f.response 376 } 377 378 // Endpoints returns the http endpoints of the function 379 func (f FunctionDescriptor) Endpoints() []http.Endpoint { 380 return f.endpoints 381 } 382 383 // Annotations returns the annotations of the function 384 func (f FunctionDescriptor) Annotations() []parser.Annotation { 385 return f.annotations 386 } 387 388 // ServiceDescriptor is the runtime descriptor of a service 389 type ServiceDescriptor struct { 390 name string 391 functions map[string]*FunctionDescriptor 392 annotations []parser.Annotation 393 } 394 395 // Name returns the name of the service 396 func (s ServiceDescriptor) Name() string { 397 return s.name 398 } 399 400 // Functions returns all functions in the service 401 func (s ServiceDescriptor) Functions() map[string]*FunctionDescriptor { 402 return s.functions 403 } 404 405 // LookupFunctionByMethod lookup function by method name 406 func (s *ServiceDescriptor) LookupFunctionByMethod(method string) (*FunctionDescriptor, error) { 407 fnSvc, ok := s.functions[method] 408 if !ok { 409 return nil, fmt.Errorf("missing method: %s in service: %s", method, s.name) 410 } 411 return fnSvc, nil 412 } 413 414 // Annotations returns the annotations of a service 415 func (s ServiceDescriptor) Annotations() []parser.Annotation { 416 return s.annotations 417 } 418 419 // Requireness is the requireness of a field. 420 // See also https://thrift.apache.org/docs/idl.html 421 type Requireness uint8 422 423 const ( 424 // OptionalRequireness means the field is optional 425 OptionalRequireness Requireness = 0 426 // DefaultRequireness means the field is default-requireness 427 DefaultRequireness Requireness = 1 428 // RequiredRequireness means the field is required 429 RequiredRequireness Requireness = 2 430 )