1// Copyright 2019 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
5package reflectlite
6
7import (
8	"unsafe"
9)
10
11// Field returns the i'th field of the struct v.
12// It panics if v's Kind is not Struct or i is out of range.
13func Field(v Value, i int) Value {
14	if v.kind() != Struct {
15		panic(&ValueError{"reflect.Value.Field", v.kind()})
16	}
17	tt := (*structType)(unsafe.Pointer(v.typ()))
18	if uint(i) >= uint(len(tt.Fields)) {
19		panic("reflect: Field index out of range")
20	}
21	field := &tt.Fields[i]
22	typ := field.Typ
23
24	// Inherit permission bits from v, but clear flagEmbedRO.
25	fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
26	// Using an unexported field forces flagRO.
27	if !field.Name.IsExported() {
28		if field.Embedded() {
29			fl |= flagEmbedRO
30		} else {
31			fl |= flagStickyRO
32		}
33	}
34	// Either flagIndir is set and v.ptr points at struct,
35	// or flagIndir is not set and v.ptr is the actual struct data.
36	// In the former case, we want v.ptr + offset.
37	// In the latter case, we must have field.offset = 0,
38	// so v.ptr + field.offset is still the correct address.
39	ptr := add(v.ptr, field.Offset, "same as non-reflect &v.field")
40	return Value{typ, ptr, fl}
41}
42
43func TField(typ Type, i int) Type {
44	t := typ.(rtype)
45	if t.Kind() != Struct {
46		panic("reflect: Field of non-struct type")
47	}
48	tt := (*structType)(unsafe.Pointer(t.Type))
49
50	return StructFieldType(tt, i)
51}
52
53// Field returns the i'th struct field.
54func StructFieldType(t *structType, i int) Type {
55	if i < 0 || i >= len(t.Fields) {
56		panic("reflect: Field index out of bounds")
57	}
58	p := &t.Fields[i]
59	return toType(p.Typ)
60}
61
62// Zero returns a Value representing the zero value for the specified type.
63// The result is different from the zero value of the Value struct,
64// which represents no value at all.
65// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
66// The returned value is neither addressable nor settable.
67func Zero(typ Type) Value {
68	if typ == nil {
69		panic("reflect: Zero(nil)")
70	}
71	t := typ.common()
72	fl := flag(t.Kind())
73	if t.IfaceIndir() {
74		return Value{t, unsafe_New(t), fl | flagIndir}
75	}
76	return Value{t, nil, fl}
77}
78
79// ToInterface returns v's current value as an interface{}.
80// It is equivalent to:
81//
82//	var i interface{} = (v's underlying value)
83//
84// It panics if the Value was obtained by accessing
85// unexported struct fields.
86func ToInterface(v Value) (i any) {
87	return valueInterface(v)
88}
89
90type EmbedWithUnexpMeth struct{}
91
92func (EmbedWithUnexpMeth) f() {}
93
94type pinUnexpMeth interface {
95	f()
96}
97
98var pinUnexpMethI = pinUnexpMeth(EmbedWithUnexpMeth{})
99
100func FirstMethodNameBytes(t Type) *byte {
101	_ = pinUnexpMethI
102
103	ut := t.uncommon()
104	if ut == nil {
105		panic("type has no methods")
106	}
107	m := ut.Methods()[0]
108	mname := t.(rtype).nameOff(m.Name)
109	if *mname.DataChecked(0, "name flag field")&(1<<2) == 0 {
110		panic("method name does not have pkgPath *string")
111	}
112	return mname.Bytes
113}
114
115type Buffer struct {
116	buf []byte
117}
118