github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/reflect/type.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Type information of an interface is stored as a pointer to a global in the
     6  // interface type (runtime._interface). This is called a type struct.
     7  // It always starts with a byte that contains both the type kind and a few
     8  // flags. In most cases it also contains a pointer to another type struct
     9  // (ptrTo), that is the pointer type of the current type (for example, type int
    10  // also has a pointer to the type *int). The exception is pointer types, to
    11  // avoid infinite recursion.
    12  //
    13  // The layouts specifically look like this:
    14  // - basic types (Bool..UnsafePointer):
    15  //     meta         uint8 // actually: kind + flags
    16  //     ptrTo        *typeStruct
    17  // - channels and slices (see elemType):
    18  //     meta          uint8
    19  //     nmethods     uint16 (0)
    20  //     ptrTo        *typeStruct
    21  //     elementType  *typeStruct // the type that you get with .Elem()
    22  // - pointer types (see ptrType, this doesn't include chan, map, etc):
    23  //     meta         uint8
    24  //     nmethods     uint16
    25  //     elementType  *typeStruct
    26  // - array types (see arrayType)
    27  //     meta         uint8
    28  //     nmethods     uint16 (0)
    29  //     ptrTo        *typeStruct
    30  //     elem         *typeStruct // element type of the array
    31  //     arrayLen     uintptr     // length of the array (this is part of the type)
    32  //     slicePtr     *typeStruct // pointer to []T type
    33  // - map types (this is still missing the key and element types)
    34  //     meta         uint8
    35  //     nmethods     uint16 (0)
    36  //     ptrTo        *typeStruct
    37  //     elem         *typeStruct
    38  //     key          *typeStruct
    39  // - struct types (see structType):
    40  //     meta         uint8
    41  //     nmethods     uint16
    42  //     ptrTo        *typeStruct
    43  //     size         uint32
    44  //     pkgpath      *byte       // package path; null terminated
    45  //     numField     uint16
    46  //     fields       [...]structField // the remaining fields are all of type structField
    47  // - interface types (this is missing the interface methods):
    48  //     meta         uint8
    49  //     ptrTo        *typeStruct
    50  // - signature types (this is missing input and output parameters):
    51  //     meta         uint8
    52  //     ptrTo        *typeStruct
    53  // - named types
    54  //     meta         uint8
    55  //     nmethods     uint16      // number of methods
    56  //     ptrTo        *typeStruct
    57  //     elem         *typeStruct // underlying type
    58  //     pkgpath      *byte       // pkgpath; null terminated
    59  //     name         [1]byte     // actual name; null terminated
    60  //
    61  // The type struct is essentially a union of all the above types. Which it is,
    62  // can be determined by looking at the meta byte.
    63  
    64  package reflect
    65  
    66  import (
    67  	"internal/itoa"
    68  	"unsafe"
    69  )
    70  
    71  // Flags stored in the first byte of the struct field byte array. Must be kept
    72  // up to date with compiler/interface.go.
    73  const (
    74  	structFieldFlagAnonymous = 1 << iota
    75  	structFieldFlagHasTag
    76  	structFieldFlagIsExported
    77  	structFieldFlagIsEmbedded
    78  )
    79  
    80  type Kind uint8
    81  
    82  // Copied from reflect/type.go
    83  // https://golang.org/src/reflect/type.go?s=8302:8316#L217
    84  // These constants must match basicTypes and the typeKind* constants in
    85  // compiler/interface.go
    86  const (
    87  	Invalid Kind = iota
    88  	Bool
    89  	Int
    90  	Int8
    91  	Int16
    92  	Int32
    93  	Int64
    94  	Uint
    95  	Uint8
    96  	Uint16
    97  	Uint32
    98  	Uint64
    99  	Uintptr
   100  	Float32
   101  	Float64
   102  	Complex64
   103  	Complex128
   104  	String
   105  	UnsafePointer
   106  	Chan
   107  	Interface
   108  	Pointer
   109  	Slice
   110  	Array
   111  	Func
   112  	Map
   113  	Struct
   114  )
   115  
   116  // Ptr is the old name for the Pointer kind.
   117  const Ptr = Pointer
   118  
   119  func (k Kind) String() string {
   120  	switch k {
   121  	case Invalid:
   122  		return "invalid"
   123  	case Bool:
   124  		return "bool"
   125  	case Int:
   126  		return "int"
   127  	case Int8:
   128  		return "int8"
   129  	case Int16:
   130  		return "int16"
   131  	case Int32:
   132  		return "int32"
   133  	case Int64:
   134  		return "int64"
   135  	case Uint:
   136  		return "uint"
   137  	case Uint8:
   138  		return "uint8"
   139  	case Uint16:
   140  		return "uint16"
   141  	case Uint32:
   142  		return "uint32"
   143  	case Uint64:
   144  		return "uint64"
   145  	case Uintptr:
   146  		return "uintptr"
   147  	case Float32:
   148  		return "float32"
   149  	case Float64:
   150  		return "float64"
   151  	case Complex64:
   152  		return "complex64"
   153  	case Complex128:
   154  		return "complex128"
   155  	case String:
   156  		return "string"
   157  	case UnsafePointer:
   158  		return "unsafe.Pointer"
   159  	case Chan:
   160  		return "chan"
   161  	case Interface:
   162  		return "interface"
   163  	case Pointer:
   164  		return "ptr"
   165  	case Slice:
   166  		return "slice"
   167  	case Array:
   168  		return "array"
   169  	case Func:
   170  		return "func"
   171  	case Map:
   172  		return "map"
   173  	case Struct:
   174  		return "struct"
   175  	default:
   176  		return "kind" + itoa.Itoa(int(int8(k)))
   177  	}
   178  }
   179  
   180  // Copied from reflect/type.go
   181  // https://go.dev/src/reflect/type.go?#L348
   182  
   183  // ChanDir represents a channel type's direction.
   184  type ChanDir int
   185  
   186  const (
   187  	RecvDir ChanDir             = 1 << iota // <-chan
   188  	SendDir                                 // chan<-
   189  	BothDir = RecvDir | SendDir             // chan
   190  )
   191  
   192  // Method represents a single method.
   193  type Method struct {
   194  	// Name is the method name.
   195  	Name string
   196  
   197  	// PkgPath is the package path that qualifies a lower case (unexported)
   198  	// method name. It is empty for upper case (exported) method names.
   199  	// The combination of PkgPath and Name uniquely identifies a method
   200  	// in a method set.
   201  	// See https://golang.org/ref/spec#Uniqueness_of_identifiers
   202  	PkgPath string
   203  
   204  	Type  Type  // method type
   205  	Func  Value // func with receiver as first argument
   206  	Index int   // index for Type.Method
   207  }
   208  
   209  // The following Type type has been copied almost entirely from
   210  // https://github.com/golang/go/blob/go1.15/src/reflect/type.go#L27-L212.
   211  // Some methods have been commented out as they haven't yet been implemented.
   212  
   213  // Type is the representation of a Go type.
   214  //
   215  // Not all methods apply to all kinds of types. Restrictions,
   216  // if any, are noted in the documentation for each method.
   217  // Use the Kind method to find out the kind of type before
   218  // calling kind-specific methods. Calling a method
   219  // inappropriate to the kind of type causes a run-time panic.
   220  //
   221  // Type values are comparable, such as with the == operator,
   222  // so they can be used as map keys.
   223  // Two Type values are equal if they represent identical types.
   224  type Type interface {
   225  	// Methods applicable to all types.
   226  
   227  	// Align returns the alignment in bytes of a value of
   228  	// this type when allocated in memory.
   229  	Align() int
   230  
   231  	// FieldAlign returns the alignment in bytes of a value of
   232  	// this type when used as a field in a struct.
   233  	FieldAlign() int
   234  
   235  	// Method returns the i'th method in the type's method set.
   236  	// It panics if i is not in the range [0, NumMethod()).
   237  	//
   238  	// For a non-interface type T or *T, the returned Method's Type and Func
   239  	// fields describe a function whose first argument is the receiver.
   240  	//
   241  	// For an interface type, the returned Method's Type field gives the
   242  	// method signature, without a receiver, and the Func field is nil.
   243  	//
   244  	// Only exported methods are accessible and they are sorted in
   245  	// lexicographic order.
   246  	Method(int) Method
   247  
   248  	// MethodByName returns the method with that name in the type's
   249  	// method set and a boolean indicating if the method was found.
   250  	//
   251  	// For a non-interface type T or *T, the returned Method's Type and Func
   252  	// fields describe a function whose first argument is the receiver.
   253  	//
   254  	// For an interface type, the returned Method's Type field gives the
   255  	// method signature, without a receiver, and the Func field is nil.
   256  	MethodByName(string) (Method, bool)
   257  
   258  	// NumMethod returns the number of exported methods in the type's method set.
   259  	NumMethod() int
   260  
   261  	// Name returns the type's name within its package for a defined type.
   262  	// For other (non-defined) types it returns the empty string.
   263  	Name() string
   264  
   265  	// PkgPath returns a defined type's package path, that is, the import path
   266  	// that uniquely identifies the package, such as "encoding/base64".
   267  	// If the type was predeclared (string, error) or not defined (*T, struct{},
   268  	// []int, or A where A is an alias for a non-defined type), the package path
   269  	// will be the empty string.
   270  	PkgPath() string
   271  
   272  	// Size returns the number of bytes needed to store
   273  	// a value of the given type; it is analogous to unsafe.Sizeof.
   274  	Size() uintptr
   275  
   276  	// String returns a string representation of the type.
   277  	// The string representation may use shortened package names
   278  	// (e.g., base64 instead of "encoding/base64") and is not
   279  	// guaranteed to be unique among types. To test for type identity,
   280  	// compare the Types directly.
   281  	String() string
   282  
   283  	// Kind returns the specific kind of this type.
   284  	Kind() Kind
   285  
   286  	// Implements reports whether the type implements the interface type u.
   287  	Implements(u Type) bool
   288  
   289  	// AssignableTo reports whether a value of the type is assignable to type u.
   290  	AssignableTo(u Type) bool
   291  
   292  	// ConvertibleTo reports whether a value of the type is convertible to type u.
   293  	ConvertibleTo(u Type) bool
   294  
   295  	// Comparable reports whether values of this type are comparable.
   296  	Comparable() bool
   297  
   298  	// Methods applicable only to some types, depending on Kind.
   299  	// The methods allowed for each kind are:
   300  	//
   301  	//	Int*, Uint*, Float*, Complex*: Bits
   302  	//	Array: Elem, Len
   303  	//	Chan: ChanDir, Elem
   304  	//	Func: In, NumIn, Out, NumOut, IsVariadic.
   305  	//	Map: Key, Elem
   306  	//	Pointer: Elem
   307  	//	Slice: Elem
   308  	//	Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField
   309  
   310  	// Bits returns the size of the type in bits.
   311  	// It panics if the type's Kind is not one of the
   312  	// sized or unsized Int, Uint, Float, or Complex kinds.
   313  	Bits() int
   314  
   315  	// ChanDir returns a channel type's direction.
   316  	// It panics if the type's Kind is not Chan.
   317  	ChanDir() ChanDir
   318  
   319  	// IsVariadic reports whether a function type's final input parameter
   320  	// is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's
   321  	// implicit actual type []T.
   322  	//
   323  	// For concreteness, if t represents func(x int, y ... float64), then
   324  	//
   325  	//	t.NumIn() == 2
   326  	//	t.In(0) is the reflect.Type for "int"
   327  	//	t.In(1) is the reflect.Type for "[]float64"
   328  	//	t.IsVariadic() == true
   329  	//
   330  	// IsVariadic panics if the type's Kind is not Func.
   331  	IsVariadic() bool
   332  
   333  	// Elem returns a type's element type.
   334  	// It panics if the type's Kind is not Array, Chan, Map, Pointer, or Slice.
   335  	Elem() Type
   336  
   337  	// Field returns a struct type's i'th field.
   338  	// It panics if the type's Kind is not Struct.
   339  	// It panics if i is not in the range [0, NumField()).
   340  	Field(i int) StructField
   341  
   342  	// FieldByIndex returns the nested field corresponding
   343  	// to the index sequence. It is equivalent to calling Field
   344  	// successively for each index i.
   345  	// It panics if the type's Kind is not Struct.
   346  	FieldByIndex(index []int) StructField
   347  
   348  	// FieldByName returns the struct field with the given name
   349  	// and a boolean indicating if the field was found.
   350  	FieldByName(name string) (StructField, bool)
   351  
   352  	// FieldByNameFunc returns the struct field with a name
   353  	// that satisfies the match function and a boolean indicating if
   354  	// the field was found.
   355  	//
   356  	// FieldByNameFunc considers the fields in the struct itself
   357  	// and then the fields in any embedded structs, in breadth first order,
   358  	// stopping at the shallowest nesting depth containing one or more
   359  	// fields satisfying the match function. If multiple fields at that depth
   360  	// satisfy the match function, they cancel each other
   361  	// and FieldByNameFunc returns no match.
   362  	// This behavior mirrors Go's handling of name lookup in
   363  	// structs containing embedded fields.
   364  	FieldByNameFunc(match func(string) bool) (StructField, bool)
   365  
   366  	// In returns the type of a function type's i'th input parameter.
   367  	// It panics if the type's Kind is not Func.
   368  	// It panics if i is not in the range [0, NumIn()).
   369  	In(i int) Type
   370  
   371  	// Key returns a map type's key type.
   372  	// It panics if the type's Kind is not Map.
   373  	Key() Type
   374  
   375  	// Len returns an array type's length.
   376  	// It panics if the type's Kind is not Array.
   377  	Len() int
   378  
   379  	// NumField returns a struct type's field count.
   380  	// It panics if the type's Kind is not Struct.
   381  	NumField() int
   382  
   383  	// NumIn returns a function type's input parameter count.
   384  	// It panics if the type's Kind is not Func.
   385  	NumIn() int
   386  
   387  	// NumOut returns a function type's output parameter count.
   388  	// It panics if the type's Kind is not Func.
   389  	NumOut() int
   390  
   391  	// Out returns the type of a function type's i'th output parameter.
   392  	// It panics if the type's Kind is not Func.
   393  	// It panics if i is not in the range [0, NumOut()).
   394  	Out(i int) Type
   395  }
   396  
   397  // Constants for the 'meta' byte.
   398  const (
   399  	kindMask       = 31  // mask to apply to the meta byte to get the Kind value
   400  	flagNamed      = 32  // flag that is set if this is a named type
   401  	flagComparable = 64  // flag that is set if this type is comparable
   402  	flagIsBinary   = 128 // flag that is set if this type uses the hashmap binary algorithm
   403  )
   404  
   405  // The base type struct. All type structs start with this.
   406  type rawType struct {
   407  	meta uint8 // metadata byte, contains kind and flags (see contants above)
   408  }
   409  
   410  // All types that have an element type: named, chan, slice, array, map (but not
   411  // pointer because it doesn't have ptrTo).
   412  type elemType struct {
   413  	rawType
   414  	numMethod uint16
   415  	ptrTo     *rawType
   416  	elem      *rawType
   417  }
   418  
   419  type ptrType struct {
   420  	rawType
   421  	numMethod uint16
   422  	elem      *rawType
   423  }
   424  
   425  type arrayType struct {
   426  	rawType
   427  	numMethod uint16
   428  	ptrTo     *rawType
   429  	elem      *rawType
   430  	arrayLen  uintptr
   431  	slicePtr  *rawType
   432  }
   433  
   434  type mapType struct {
   435  	rawType
   436  	numMethod uint16
   437  	ptrTo     *rawType
   438  	elem      *rawType
   439  	key       *rawType
   440  }
   441  
   442  type namedType struct {
   443  	rawType
   444  	numMethod uint16
   445  	ptrTo     *rawType
   446  	elem      *rawType
   447  	pkg       *byte
   448  	name      [1]byte
   449  }
   450  
   451  // Type for struct types. The numField value is intentionally put before ptrTo
   452  // for better struct packing on 32-bit and 64-bit architectures. On these
   453  // architectures, the ptrTo field still has the same offset as in all the other
   454  // type structs.
   455  // The fields array isn't necessarily 1 structField long, instead it is as long
   456  // as numFields. The array is given a length of 1 to satisfy the Go type
   457  // checker.
   458  type structType struct {
   459  	rawType
   460  	numMethod uint16
   461  	ptrTo     *rawType
   462  	pkgpath   *byte
   463  	size      uint32
   464  	numField  uint16
   465  	fields    [1]structField // the remaining fields are all of type structField
   466  }
   467  
   468  type structField struct {
   469  	fieldType *rawType
   470  	data      unsafe.Pointer // various bits of information, packed in a byte array
   471  }
   472  
   473  // Equivalent to (go/types.Type).Underlying(): if this is a named type return
   474  // the underlying type, else just return the type itself.
   475  func (t *rawType) underlying() *rawType {
   476  	if t.isNamed() {
   477  		return (*elemType)(unsafe.Pointer(t)).elem
   478  	}
   479  	return t
   480  }
   481  
   482  func (t *rawType) ptrtag() uintptr {
   483  	return uintptr(unsafe.Pointer(t)) & 0b11
   484  }
   485  
   486  func (t *rawType) isNamed() bool {
   487  	if tag := t.ptrtag(); tag != 0 {
   488  		return false
   489  	}
   490  
   491  	return t.meta&flagNamed != 0
   492  }
   493  
   494  func TypeOf(i interface{}) Type {
   495  	if i == nil {
   496  		return nil
   497  	}
   498  	typecode, _ := decomposeInterface(i)
   499  	return (*rawType)(typecode)
   500  }
   501  
   502  func PtrTo(t Type) Type { return PointerTo(t) }
   503  
   504  func PointerTo(t Type) Type {
   505  	return pointerTo(t.(*rawType))
   506  }
   507  
   508  func pointerTo(t *rawType) *rawType {
   509  	if t.isNamed() {
   510  		return (*elemType)(unsafe.Pointer(t)).ptrTo
   511  	}
   512  
   513  	switch t.Kind() {
   514  	case Pointer:
   515  		if tag := t.ptrtag(); tag < 3 {
   516  			return (*rawType)(unsafe.Add(unsafe.Pointer(t), 1))
   517  		}
   518  
   519  		// TODO(dgryski): This is blocking https://github.com/tinygo-org/tinygo/issues/3131
   520  		// We need to be able to create types that match existing types to prevent typecode equality.
   521  		panic("reflect: cannot make *****T type")
   522  	case Struct:
   523  		return (*structType)(unsafe.Pointer(t)).ptrTo
   524  	default:
   525  		return (*elemType)(unsafe.Pointer(t)).ptrTo
   526  	}
   527  }
   528  
   529  func (t *rawType) String() string {
   530  	if t.isNamed() {
   531  		s := t.name()
   532  		if s[0] == '.' {
   533  			return s[1:]
   534  		}
   535  		return s
   536  	}
   537  
   538  	switch t.Kind() {
   539  	case Chan:
   540  		elem := t.elem().String()
   541  		switch t.ChanDir() {
   542  		case SendDir:
   543  			return "chan<- " + elem
   544  		case RecvDir:
   545  			return "<-chan " + elem
   546  		case BothDir:
   547  			if elem[0] == '<' {
   548  				// typ is recv chan, need parentheses as "<-" associates with leftmost
   549  				// chan possible, see:
   550  				// * https://golang.org/ref/spec#Channel_types
   551  				// * https://github.com/golang/go/issues/39897
   552  				return "chan (" + elem + ")"
   553  			}
   554  			return "chan " + elem
   555  		}
   556  
   557  	case Pointer:
   558  		return "*" + t.elem().String()
   559  	case Slice:
   560  		return "[]" + t.elem().String()
   561  	case Array:
   562  		return "[" + itoa.Itoa(t.Len()) + "]" + t.elem().String()
   563  	case Map:
   564  		return "map[" + t.key().String() + "]" + t.elem().String()
   565  	case Struct:
   566  		numField := t.NumField()
   567  		if numField == 0 {
   568  			return "struct {}"
   569  		}
   570  		s := "struct {"
   571  		for i := 0; i < numField; i++ {
   572  			f := t.rawField(i)
   573  			s += " " + f.Name + " " + f.Type.String()
   574  			if f.Tag != "" {
   575  				s += " " + quote(string(f.Tag))
   576  			}
   577  			// every field except the last needs a semicolon
   578  			if i < numField-1 {
   579  				s += ";"
   580  			}
   581  		}
   582  		s += " }"
   583  		return s
   584  	case Interface:
   585  		// TODO(dgryski): Needs actual method set info
   586  		return "interface {}"
   587  	default:
   588  		return t.Kind().String()
   589  	}
   590  
   591  	return t.Kind().String()
   592  }
   593  
   594  func (t *rawType) Kind() Kind {
   595  	if t == nil {
   596  		return Invalid
   597  	}
   598  
   599  	if tag := t.ptrtag(); tag != 0 {
   600  		return Pointer
   601  	}
   602  
   603  	return Kind(t.meta & kindMask)
   604  }
   605  
   606  var (
   607  	errTypeElem         = &TypeError{"Elem"}
   608  	errTypeKey          = &TypeError{"Key"}
   609  	errTypeField        = &TypeError{"Field"}
   610  	errTypeBits         = &TypeError{"Bits"}
   611  	errTypeLen          = &TypeError{"Len"}
   612  	errTypeNumField     = &TypeError{"NumField"}
   613  	errTypeChanDir      = &TypeError{"ChanDir"}
   614  	errTypeFieldByName  = &TypeError{"FieldByName"}
   615  	errTypeFieldByIndex = &TypeError{"FieldByIndex"}
   616  )
   617  
   618  // Elem returns the element type for channel, slice and array types, the
   619  // pointed-to value for pointer types, and the key type for map types.
   620  func (t *rawType) Elem() Type {
   621  	return t.elem()
   622  }
   623  
   624  func (t *rawType) elem() *rawType {
   625  	if tag := t.ptrtag(); tag != 0 {
   626  		return (*rawType)(unsafe.Add(unsafe.Pointer(t), -1))
   627  	}
   628  
   629  	underlying := t.underlying()
   630  	switch underlying.Kind() {
   631  	case Pointer:
   632  		return (*ptrType)(unsafe.Pointer(underlying)).elem
   633  	case Chan, Slice, Array, Map:
   634  		return (*elemType)(unsafe.Pointer(underlying)).elem
   635  	default:
   636  		panic(errTypeElem)
   637  	}
   638  }
   639  
   640  func (t *rawType) key() *rawType {
   641  	underlying := t.underlying()
   642  	if underlying.Kind() != Map {
   643  		panic(errTypeKey)
   644  	}
   645  	return (*mapType)(unsafe.Pointer(underlying)).key
   646  }
   647  
   648  // Field returns the type of the i'th field of this struct type. It panics if t
   649  // is not a struct type.
   650  func (t *rawType) Field(i int) StructField {
   651  	field := t.rawField(i)
   652  	return StructField{
   653  		Name:      field.Name,
   654  		PkgPath:   field.PkgPath,
   655  		Type:      field.Type, // note: converts rawType to Type
   656  		Tag:       field.Tag,
   657  		Anonymous: field.Anonymous,
   658  		Offset:    field.Offset,
   659  		Index:     []int{i},
   660  	}
   661  }
   662  
   663  func rawStructFieldFromPointer(descriptor *structType, fieldType *rawType, data unsafe.Pointer, flagsByte uint8, name string, offset uint32) rawStructField {
   664  	// Read the field tag, if there is one.
   665  	var tag string
   666  	if flagsByte&structFieldFlagHasTag != 0 {
   667  		data = unsafe.Add(data, 1) // C: data+1
   668  		tagLen := uintptr(*(*byte)(data))
   669  		data = unsafe.Add(data, 1) // C: data+1
   670  		tag = *(*string)(unsafe.Pointer(&stringHeader{
   671  			data: data,
   672  			len:  tagLen,
   673  		}))
   674  	}
   675  
   676  	// Set the PkgPath to some (arbitrary) value if the package path is not
   677  	// exported.
   678  	pkgPath := ""
   679  	if flagsByte&structFieldFlagIsExported == 0 {
   680  		// This field is unexported.
   681  		pkgPath = readStringZ(unsafe.Pointer(descriptor.pkgpath))
   682  	}
   683  
   684  	return rawStructField{
   685  		Name:      name,
   686  		PkgPath:   pkgPath,
   687  		Type:      fieldType,
   688  		Tag:       StructTag(tag),
   689  		Anonymous: flagsByte&structFieldFlagAnonymous != 0,
   690  		Offset:    uintptr(offset),
   691  	}
   692  }
   693  
   694  // rawField returns nearly the same value as Field but without converting the
   695  // Type member to an interface.
   696  //
   697  // For internal use only.
   698  func (t *rawType) rawField(n int) rawStructField {
   699  	if t.Kind() != Struct {
   700  		panic(errTypeField)
   701  	}
   702  	descriptor := (*structType)(unsafe.Pointer(t.underlying()))
   703  	if uint(n) >= uint(descriptor.numField) {
   704  		panic("reflect: field index out of range")
   705  	}
   706  
   707  	// Iterate over all the fields to calculate the offset.
   708  	// This offset could have been stored directly in the array (to make the
   709  	// lookup faster), but by calculating it on-the-fly a bit of storage can be
   710  	// saved.
   711  	field := (*structField)(unsafe.Add(unsafe.Pointer(&descriptor.fields[0]), uintptr(n)*unsafe.Sizeof(structField{})))
   712  	data := field.data
   713  
   714  	// Read some flags of this field, like whether the field is an embedded
   715  	// field. See structFieldFlagAnonymous and similar flags.
   716  	flagsByte := *(*byte)(data)
   717  	data = unsafe.Add(data, 1)
   718  	offset, lenOffs := uvarint32(unsafe.Slice((*byte)(data), maxVarintLen32))
   719  	data = unsafe.Add(data, lenOffs)
   720  
   721  	name := readStringZ(data)
   722  	data = unsafe.Add(data, len(name))
   723  
   724  	return rawStructFieldFromPointer(descriptor, field.fieldType, data, flagsByte, name, offset)
   725  }
   726  
   727  // rawFieldByNameFunc returns nearly the same value as FieldByNameFunc but without converting the
   728  // Type member to an interface.
   729  //
   730  // For internal use only.
   731  func (t *rawType) rawFieldByNameFunc(match func(string) bool) (rawStructField, []int, bool) {
   732  	if t.Kind() != Struct {
   733  		panic(errTypeField)
   734  	}
   735  
   736  	type fieldWalker struct {
   737  		t     *rawType
   738  		index []int
   739  	}
   740  
   741  	queue := make([]fieldWalker, 0, 4)
   742  	queue = append(queue, fieldWalker{t, nil})
   743  
   744  	for len(queue) > 0 {
   745  		type result struct {
   746  			r     rawStructField
   747  			index []int
   748  		}
   749  
   750  		var found []result
   751  		var nextlevel []fieldWalker
   752  
   753  		// For all the structs at this level..
   754  		for _, ll := range queue {
   755  			// Iterate over all the fields looking for the matching name
   756  			// Also calculate field offset.
   757  
   758  			descriptor := (*structType)(unsafe.Pointer(ll.t.underlying()))
   759  			field := &descriptor.fields[0]
   760  
   761  			for i := uint16(0); i < descriptor.numField; i++ {
   762  				data := field.data
   763  
   764  				// Read some flags of this field, like whether the field is an embedded
   765  				// field. See structFieldFlagAnonymous and similar flags.
   766  				flagsByte := *(*byte)(data)
   767  				data = unsafe.Add(data, 1)
   768  
   769  				offset, lenOffs := uvarint32(unsafe.Slice((*byte)(data), maxVarintLen32))
   770  				data = unsafe.Add(data, lenOffs)
   771  
   772  				name := readStringZ(data)
   773  				data = unsafe.Add(data, len(name))
   774  				if match(name) {
   775  					found = append(found, result{
   776  						rawStructFieldFromPointer(descriptor, field.fieldType, data, flagsByte, name, offset),
   777  						append(ll.index, int(i)),
   778  					})
   779  				}
   780  
   781  				structOrPtrToStruct := field.fieldType.Kind() == Struct || (field.fieldType.Kind() == Pointer && field.fieldType.elem().Kind() == Struct)
   782  				if flagsByte&structFieldFlagIsEmbedded == structFieldFlagIsEmbedded && structOrPtrToStruct {
   783  					embedded := field.fieldType
   784  					if embedded.Kind() == Pointer {
   785  						embedded = embedded.elem()
   786  					}
   787  
   788  					nextlevel = append(nextlevel, fieldWalker{
   789  						t:     embedded,
   790  						index: append(ll.index, int(i)),
   791  					})
   792  				}
   793  
   794  				// update offset/field pointer if there *is* a next field
   795  				if i < descriptor.numField-1 {
   796  					// Increment pointer to the next field.
   797  					field = (*structField)(unsafe.Add(unsafe.Pointer(field), unsafe.Sizeof(structField{})))
   798  				}
   799  			}
   800  		}
   801  
   802  		// found multiple hits at this level
   803  		if len(found) > 1 {
   804  			return rawStructField{}, nil, false
   805  		}
   806  
   807  		// found the field we were looking for
   808  		if len(found) == 1 {
   809  			r := found[0]
   810  			return r.r, r.index, true
   811  		}
   812  
   813  		// else len(found) == 0, move on to the next level
   814  		queue = append(queue[:0], nextlevel...)
   815  	}
   816  
   817  	// didn't find it
   818  	return rawStructField{}, nil, false
   819  }
   820  
   821  // Bits returns the number of bits that this type uses. It is only valid for
   822  // arithmetic types (integers, floats, and complex numbers). For other types, it
   823  // will panic.
   824  func (t *rawType) Bits() int {
   825  	kind := t.Kind()
   826  	if kind >= Int && kind <= Complex128 {
   827  		return int(t.Size()) * 8
   828  	}
   829  	panic(errTypeBits)
   830  }
   831  
   832  // Len returns the number of elements in this array. It panics of the type kind
   833  // is not Array.
   834  func (t *rawType) Len() int {
   835  	if t.Kind() != Array {
   836  		panic(errTypeLen)
   837  	}
   838  
   839  	return int((*arrayType)(unsafe.Pointer(t.underlying())).arrayLen)
   840  }
   841  
   842  // NumField returns the number of fields of a struct type. It panics for other
   843  // type kinds.
   844  func (t *rawType) NumField() int {
   845  	if t.Kind() != Struct {
   846  		panic(errTypeNumField)
   847  	}
   848  	return int((*structType)(unsafe.Pointer(t.underlying())).numField)
   849  }
   850  
   851  // Size returns the size in bytes of a given type. It is similar to
   852  // unsafe.Sizeof.
   853  func (t *rawType) Size() uintptr {
   854  	switch t.Kind() {
   855  	case Bool, Int8, Uint8:
   856  		return 1
   857  	case Int16, Uint16:
   858  		return 2
   859  	case Int32, Uint32:
   860  		return 4
   861  	case Int64, Uint64:
   862  		return 8
   863  	case Int, Uint:
   864  		return unsafe.Sizeof(int(0))
   865  	case Uintptr:
   866  		return unsafe.Sizeof(uintptr(0))
   867  	case Float32:
   868  		return 4
   869  	case Float64:
   870  		return 8
   871  	case Complex64:
   872  		return 8
   873  	case Complex128:
   874  		return 16
   875  	case String:
   876  		return unsafe.Sizeof("")
   877  	case UnsafePointer, Chan, Map, Pointer:
   878  		return unsafe.Sizeof(uintptr(0))
   879  	case Slice:
   880  		return unsafe.Sizeof([]int{})
   881  	case Interface:
   882  		return unsafe.Sizeof(interface{}(nil))
   883  	case Func:
   884  		var f func()
   885  		return unsafe.Sizeof(f)
   886  	case Array:
   887  		return t.elem().Size() * uintptr(t.Len())
   888  	case Struct:
   889  		u := t.underlying()
   890  		return uintptr((*structType)(unsafe.Pointer(u)).size)
   891  	default:
   892  		panic("unimplemented: size of type")
   893  	}
   894  }
   895  
   896  // Align returns the alignment of this type. It is similar to calling
   897  // unsafe.Alignof.
   898  func (t *rawType) Align() int {
   899  	switch t.Kind() {
   900  	case Bool, Int8, Uint8:
   901  		return int(unsafe.Alignof(int8(0)))
   902  	case Int16, Uint16:
   903  		return int(unsafe.Alignof(int16(0)))
   904  	case Int32, Uint32:
   905  		return int(unsafe.Alignof(int32(0)))
   906  	case Int64, Uint64:
   907  		return int(unsafe.Alignof(int64(0)))
   908  	case Int, Uint:
   909  		return int(unsafe.Alignof(int(0)))
   910  	case Uintptr:
   911  		return int(unsafe.Alignof(uintptr(0)))
   912  	case Float32:
   913  		return int(unsafe.Alignof(float32(0)))
   914  	case Float64:
   915  		return int(unsafe.Alignof(float64(0)))
   916  	case Complex64:
   917  		return int(unsafe.Alignof(complex64(0)))
   918  	case Complex128:
   919  		return int(unsafe.Alignof(complex128(0)))
   920  	case String:
   921  		return int(unsafe.Alignof(""))
   922  	case UnsafePointer, Chan, Map, Pointer:
   923  		return int(unsafe.Alignof(uintptr(0)))
   924  	case Slice:
   925  		return int(unsafe.Alignof([]int(nil)))
   926  	case Interface:
   927  		return int(unsafe.Alignof(interface{}(nil)))
   928  	case Func:
   929  		var f func()
   930  		return int(unsafe.Alignof(f))
   931  	case Struct:
   932  		numField := t.NumField()
   933  		alignment := 1
   934  		for i := 0; i < numField; i++ {
   935  			fieldAlignment := t.rawField(i).Type.Align()
   936  			if fieldAlignment > alignment {
   937  				alignment = fieldAlignment
   938  			}
   939  		}
   940  		return alignment
   941  	case Array:
   942  		return t.elem().Align()
   943  	default:
   944  		panic("unimplemented: alignment of type")
   945  	}
   946  }
   947  
   948  // FieldAlign returns the alignment if this type is used in a struct field. It
   949  // is currently an alias for Align() but this might change in the future.
   950  func (t *rawType) FieldAlign() int {
   951  	return t.Align()
   952  }
   953  
   954  // AssignableTo returns whether a value of type t can be assigned to a variable
   955  // of type u.
   956  func (t *rawType) AssignableTo(u Type) bool {
   957  	if t == u.(*rawType) {
   958  		return true
   959  	}
   960  
   961  	if u.Kind() == Interface && u.NumMethod() == 0 {
   962  		return true
   963  	}
   964  
   965  	if u.Kind() == Interface {
   966  		panic("reflect: unimplemented: AssignableTo with interface")
   967  	}
   968  	return false
   969  }
   970  
   971  func (t *rawType) Implements(u Type) bool {
   972  	if u.Kind() != Interface {
   973  		panic("reflect: non-interface type passed to Type.Implements")
   974  	}
   975  	return t.AssignableTo(u)
   976  }
   977  
   978  // Comparable returns whether values of this type can be compared to each other.
   979  func (t *rawType) Comparable() bool {
   980  	return (t.meta & flagComparable) == flagComparable
   981  }
   982  
   983  // isbinary() returns if the hashmapAlgorithmBinary functions can be used on this type
   984  func (t *rawType) isBinary() bool {
   985  	return (t.meta & flagIsBinary) == flagIsBinary
   986  }
   987  
   988  func (t *rawType) ChanDir() ChanDir {
   989  	if t.Kind() != Chan {
   990  		panic(errTypeChanDir)
   991  	}
   992  
   993  	dir := int((*elemType)(unsafe.Pointer(t)).numMethod)
   994  
   995  	// nummethod is overloaded for channel to store channel direction
   996  	return ChanDir(dir)
   997  }
   998  
   999  func (t *rawType) ConvertibleTo(u Type) bool {
  1000  	panic("unimplemented: (reflect.Type).ConvertibleTo()")
  1001  }
  1002  
  1003  func (t *rawType) IsVariadic() bool {
  1004  	panic("unimplemented: (reflect.Type).IsVariadic()")
  1005  }
  1006  
  1007  func (t *rawType) NumIn() int {
  1008  	panic("unimplemented: (reflect.Type).NumIn()")
  1009  }
  1010  
  1011  func (t *rawType) NumOut() int {
  1012  	panic("unimplemented: (reflect.Type).NumOut()")
  1013  }
  1014  
  1015  func (t *rawType) NumMethod() int {
  1016  
  1017  	if t.isNamed() {
  1018  		return int((*namedType)(unsafe.Pointer(t)).numMethod)
  1019  	}
  1020  
  1021  	switch t.Kind() {
  1022  	case Pointer:
  1023  		return int((*ptrType)(unsafe.Pointer(t)).numMethod)
  1024  	case Struct:
  1025  		return int((*structType)(unsafe.Pointer(t)).numMethod)
  1026  	}
  1027  
  1028  	// Other types have no methods attached.  Note we don't panic here.
  1029  	return 0
  1030  }
  1031  
  1032  // Read and return a null terminated string starting from data.
  1033  func readStringZ(data unsafe.Pointer) string {
  1034  	start := data
  1035  	var len uintptr
  1036  	for *(*byte)(data) != 0 {
  1037  		len++
  1038  		data = unsafe.Add(data, 1) // C: data++
  1039  	}
  1040  
  1041  	return *(*string)(unsafe.Pointer(&stringHeader{
  1042  		data: start,
  1043  		len:  len,
  1044  	}))
  1045  }
  1046  
  1047  func (t *rawType) name() string {
  1048  	ntype := (*namedType)(unsafe.Pointer(t))
  1049  	return readStringZ(unsafe.Pointer(&ntype.name[0]))
  1050  }
  1051  
  1052  func (t *rawType) Name() string {
  1053  	if t.isNamed() {
  1054  		name := t.name()
  1055  		for i := 0; i < len(name); i++ {
  1056  			if name[i] == '.' {
  1057  				return name[i+1:]
  1058  			}
  1059  		}
  1060  		panic("corrupt name data")
  1061  	}
  1062  
  1063  	if t.Kind() <= UnsafePointer {
  1064  		return t.Kind().String()
  1065  	}
  1066  
  1067  	return ""
  1068  }
  1069  
  1070  func (t *rawType) Key() Type {
  1071  	return t.key()
  1072  }
  1073  
  1074  func (t rawType) In(i int) Type {
  1075  	panic("unimplemented: (reflect.Type).In()")
  1076  }
  1077  
  1078  func (t rawType) Out(i int) Type {
  1079  	panic("unimplemented: (reflect.Type).Out()")
  1080  }
  1081  
  1082  func (t rawType) Method(i int) Method {
  1083  	panic("unimplemented: (reflect.Type).Method()")
  1084  }
  1085  
  1086  func (t rawType) MethodByName(name string) (Method, bool) {
  1087  	panic("unimplemented: (reflect.Type).MethodByName()")
  1088  }
  1089  
  1090  func (t *rawType) PkgPath() string {
  1091  	if t.isNamed() {
  1092  		ntype := (*namedType)(unsafe.Pointer(t))
  1093  		return readStringZ(unsafe.Pointer(ntype.pkg))
  1094  	}
  1095  
  1096  	return ""
  1097  }
  1098  
  1099  func (t *rawType) FieldByName(name string) (StructField, bool) {
  1100  	if t.Kind() != Struct {
  1101  		panic(errTypeFieldByName)
  1102  	}
  1103  
  1104  	field, index, ok := t.rawFieldByNameFunc(func(n string) bool { return n == name })
  1105  	if !ok {
  1106  		return StructField{}, false
  1107  	}
  1108  
  1109  	return StructField{
  1110  		Name:      field.Name,
  1111  		PkgPath:   field.PkgPath,
  1112  		Type:      field.Type, // note: converts rawType to Type
  1113  		Tag:       field.Tag,
  1114  		Anonymous: field.Anonymous,
  1115  		Offset:    field.Offset,
  1116  		Index:     index,
  1117  	}, true
  1118  }
  1119  
  1120  func (t *rawType) FieldByNameFunc(match func(string) bool) (StructField, bool) {
  1121  	if t.Kind() != Struct {
  1122  		panic(TypeError{"FieldByNameFunc"})
  1123  	}
  1124  
  1125  	field, index, ok := t.rawFieldByNameFunc(match)
  1126  	if !ok {
  1127  		return StructField{}, false
  1128  	}
  1129  
  1130  	return StructField{
  1131  		Name:      field.Name,
  1132  		PkgPath:   field.PkgPath,
  1133  		Type:      field.Type, // note: converts rawType to Type
  1134  		Tag:       field.Tag,
  1135  		Anonymous: field.Anonymous,
  1136  		Offset:    field.Offset,
  1137  		Index:     index,
  1138  	}, true
  1139  }
  1140  
  1141  func (t *rawType) FieldByIndex(index []int) StructField {
  1142  	ftype := t
  1143  	var field rawStructField
  1144  
  1145  	for _, n := range index {
  1146  		structOrPtrToStruct := ftype.Kind() == Struct || (ftype.Kind() == Pointer && ftype.elem().Kind() == Struct)
  1147  		if !structOrPtrToStruct {
  1148  			panic(errTypeFieldByIndex)
  1149  		}
  1150  
  1151  		if ftype.Kind() == Pointer {
  1152  			ftype = ftype.elem()
  1153  		}
  1154  
  1155  		field = ftype.rawField(n)
  1156  		ftype = field.Type
  1157  	}
  1158  
  1159  	return StructField{
  1160  		Name:      field.Name,
  1161  		PkgPath:   field.PkgPath,
  1162  		Type:      field.Type, // note: converts rawType to Type
  1163  		Tag:       field.Tag,
  1164  		Anonymous: field.Anonymous,
  1165  		Offset:    field.Offset,
  1166  		Index:     index,
  1167  	}
  1168  }
  1169  
  1170  // A StructField describes a single field in a struct.
  1171  type StructField struct {
  1172  	// Name indicates the field name.
  1173  	Name string
  1174  
  1175  	// PkgPath is the package path where the struct containing this field is
  1176  	// declared for unexported fields, or the empty string for exported fields.
  1177  	PkgPath string
  1178  
  1179  	Type      Type
  1180  	Tag       StructTag // field tag string
  1181  	Offset    uintptr
  1182  	Index     []int // index sequence for Type.FieldByIndex
  1183  	Anonymous bool
  1184  }
  1185  
  1186  // IsExported reports whether the field is exported.
  1187  func (f StructField) IsExported() bool {
  1188  	return f.PkgPath == ""
  1189  }
  1190  
  1191  // rawStructField is the same as StructField but with the Type member replaced
  1192  // with rawType. For internal use only. Avoiding this conversion to the Type
  1193  // interface improves code size in many cases.
  1194  type rawStructField struct {
  1195  	Name      string
  1196  	PkgPath   string
  1197  	Type      *rawType
  1198  	Tag       StructTag
  1199  	Offset    uintptr
  1200  	Anonymous bool
  1201  }
  1202  
  1203  // A StructTag is the tag string in a struct field.
  1204  type StructTag string
  1205  
  1206  // TODO: it would be feasible to do the key/value splitting at compile time,
  1207  // avoiding the code size cost of doing it at runtime
  1208  
  1209  // Get returns the value associated with key in the tag string.
  1210  func (tag StructTag) Get(key string) string {
  1211  	v, _ := tag.Lookup(key)
  1212  	return v
  1213  }
  1214  
  1215  // Lookup returns the value associated with key in the tag string.
  1216  func (tag StructTag) Lookup(key string) (value string, ok bool) {
  1217  	for tag != "" {
  1218  		// Skip leading space.
  1219  		i := 0
  1220  		for i < len(tag) && tag[i] == ' ' {
  1221  			i++
  1222  		}
  1223  		tag = tag[i:]
  1224  		if tag == "" {
  1225  			break
  1226  		}
  1227  
  1228  		// Scan to colon. A space, a quote or a control character is a syntax error.
  1229  		// Strictly speaking, control chars include the range [0x7f, 0x9f], not just
  1230  		// [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
  1231  		// as it is simpler to inspect the tag's bytes than the tag's runes.
  1232  		i = 0
  1233  		for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
  1234  			i++
  1235  		}
  1236  		if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
  1237  			break
  1238  		}
  1239  		name := string(tag[:i])
  1240  		tag = tag[i+1:]
  1241  
  1242  		// Scan quoted string to find value.
  1243  		i = 1
  1244  		for i < len(tag) && tag[i] != '"' {
  1245  			if tag[i] == '\\' {
  1246  				i++
  1247  			}
  1248  			i++
  1249  		}
  1250  		if i >= len(tag) {
  1251  			break
  1252  		}
  1253  		qvalue := string(tag[:i+1])
  1254  		tag = tag[i+1:]
  1255  
  1256  		if key == name {
  1257  			value, err := unquote(qvalue)
  1258  			if err != nil {
  1259  				break
  1260  			}
  1261  			return value, true
  1262  		}
  1263  	}
  1264  	return "", false
  1265  }
  1266  
  1267  // TypeError is the error that is used in a panic when invoking a method on a
  1268  // type that is not applicable to that type.
  1269  type TypeError struct {
  1270  	Method string
  1271  }
  1272  
  1273  func (e *TypeError) Error() string {
  1274  	return "reflect: call of reflect.Type." + e.Method + " on invalid type"
  1275  }
  1276  
  1277  func align(offset uintptr, alignment uintptr) uintptr {
  1278  	return (offset + alignment - 1) &^ (alignment - 1)
  1279  }
  1280  
  1281  func SliceOf(t Type) Type {
  1282  	panic("unimplemented: reflect.SliceOf()")
  1283  }
  1284  
  1285  func ArrayOf(n int, t Type) Type {
  1286  	panic("unimplemented: reflect.ArrayOf()")
  1287  }
  1288  
  1289  func StructOf([]StructField) Type {
  1290  	panic("unimplemented: reflect.StructOf()")
  1291  }
  1292  
  1293  func MapOf(key, value Type) Type {
  1294  	panic("unimplemented: reflect.MapOf()")
  1295  }
  1296  
  1297  func FuncOf(in, out []Type, variadic bool) Type {
  1298  	panic("unimplemented: reflect.FuncOf()")
  1299  }
  1300  
  1301  const maxVarintLen32 = 5
  1302  
  1303  // encoding/binary.Uvarint, specialized for uint32
  1304  func uvarint32(buf []byte) (uint32, int) {
  1305  	var x uint32
  1306  	var s uint
  1307  	for i, b := range buf {
  1308  		if b < 0x80 {
  1309  			return x | uint32(b)<<s, i + 1
  1310  		}
  1311  		x |= uint32(b&0x7f) << s
  1312  		s += 7
  1313  	}
  1314  	return 0, 0
  1315  }
  1316  
  1317  // TypeFor returns the [Type] that represents the type argument T.
  1318  func TypeFor[T any]() Type {
  1319  	// This function was copied from the Go 1.22 source tree.
  1320  	return TypeOf((*T)(nil)).Elem()
  1321  }