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.pkgPath != nil {
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))
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.(*rtype)
72	fl := flag(t.Kind())
73	if ifaceIndir(t) {
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//	var i interface{} = (v's underlying value)
82// It panics if the Value was obtained by accessing
83// unexported struct fields.
84func ToInterface(v Value) (i interface{}) {
85	return valueInterface(v)
86}
87
88type EmbedWithUnexpMeth struct{}
89
90func (EmbedWithUnexpMeth) f() {}
91
92type pinUnexpMeth interface {
93	f()
94}
95
96var pinUnexpMethI = pinUnexpMeth(EmbedWithUnexpMeth{})
97
98/*
99func FirstMethodNameBytes(t Type) *byte {
100	_ = pinUnexpMethI
101
102	ut := t.uncommon()
103	if ut == nil {
104		panic("type has no methods")
105	}
106	m := ut.methods[0]
107	mname := t.(*rtype).nameOff(m.name)
108	if *mname.data(0, "name flag field")&(1<<2) == 0 {
109		panic("method name does not have pkgPath *string")
110	}
111	return mname.bytes
112}
113*/
114
115type Buffer struct {
116	buf []byte
117}
118