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  )