Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package reflectlite

import (
	
	
	
)

const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
Value is the reflection interface to a Go value. Not all methods apply to all kinds of values. Restrictions, if any, are noted in the documentation for each method. Use the Kind method to find out the kind of value before calling kind-specific methods. Calling a method inappropriate to the kind of type causes a run time panic. The zero Value represents no value. Its IsValid method returns false, its Kind method returns Invalid, its String method returns "<invalid Value>", and all other methods panic. Most functions and methods never return an invalid value. If one does, its documentation states the conditions explicitly. A Value can be used concurrently by multiple goroutines provided that the underlying Go value can be used concurrently for the equivalent direct operations. To compare two Values, compare the results of the Interface method. Using == on two Values does not compare the underlying values they represent.
typ holds the type of the value represented by a Value.
Pointer-valued data or, if flagIndir is set, pointer to data. Valid when either flagIndir is set or typ.pointers() is true.
flag holds metadata about the value. The lowest bits are flag bits: - flagStickyRO: obtained via unexported not embedded field, so read-only - flagEmbedRO: obtained via unexported embedded field, so read-only - flagIndir: val holds a pointer to the data - flagAddr: v.CanAddr is true (implies flagIndir) Value cannot represent method values. The next five bits give the Kind of the value. This repeats typ.Kind() except for method values. The remaining 23+ bits give a method number for method values. If flag.kind() != Func, code can assume that flagMethod is unset. If ifaceIndir(typ), code can assume that flagIndir is set.
A method value represents a curried method invocation like r.Read for some receiver r. The typ+val+flag bits describe the receiver r, but the flag's Kind bits say Func (methods are functions), and the top bits of the flag give the method number in r's type's method table.
}

type flag uintptr

const (
	flagKindWidth        = 5 // there are 27 kinds
	flagKindMask    flag = 1<<flagKindWidth - 1
	flagStickyRO    flag = 1 << 5
	flagEmbedRO     flag = 1 << 6
	flagIndir       flag = 1 << 7
	flagAddr        flag = 1 << 8
	flagMethod      flag = 1 << 9
	flagMethodShift      = 10
	flagRO          flag = flagStickyRO | flagEmbedRO
)

func ( flag) () Kind {
	return Kind( & flagKindMask)
}

func ( flag) () flag {
	if &flagRO != 0 {
		return flagStickyRO
	}
	return 0
}
pointer returns the underlying pointer represented by v. v.Kind() must be Ptr, Map, Chan, Func, or UnsafePointer
func ( Value) () unsafe.Pointer {
	if .typ.size != ptrSize || !.typ.pointers() {
		panic("can't call pointer on a non-pointer Value")
	}
	if .flag&flagIndir != 0 {
		return *(*unsafe.Pointer)(.ptr)
	}
	return .ptr
}
packEface converts v to the empty interface.
func ( Value) interface{} {
	 := .typ
	var  interface{}
First, fill in the data portion of the interface.
	switch {
	case ifaceIndir():
		if .flag&flagIndir == 0 {
			panic("bad indir")
Value is indirect, and so is the interface we're making.
		 := .ptr
TODO: pass safe boolean from valueInterface so we don't need to copy if safe==true?
			 := unsafe_New()
			typedmemmove(, , )
			 = 
		}
		.word = 
Value is indirect, but interface is direct. We need to load the data at v.ptr into the interface data word.
		.word = *(*unsafe.Pointer)(.ptr)
Value is direct, and so is the interface.
		.word = .ptr
Now, fill in the type portion. We're very careful here not to have any operation between the e.word and e.typ assignments that would let the garbage collector observe the partially-built interface value.
	.typ = 
	return 
}
unpackEface converts the empty interface i to a Value.
func ( interface{}) Value {
NOTE: don't read e.word until we know whether it is really a pointer or not.
	 := .typ
	if  == nil {
		return Value{}
	}
	 := flag(.Kind())
	if ifaceIndir() {
		 |= flagIndir
	}
	return Value{, .word, }
}
A ValueError occurs when a Value method is invoked on a Value that does not support it. Such cases are documented in the description of each method.
type ValueError struct {
	Method string
	Kind   Kind
}

func ( *ValueError) () string {
	if .Kind == 0 {
		return "reflect: call of " + .Method + " on zero Value"
	}
	return "reflect: call of " + .Method + " on " + .Kind.String() + " Value"
}
methodName returns the name of the calling method, assumed to be two stack frames above.
func () string {
	, , ,  := runtime.Caller(2)
	 := runtime.FuncForPC()
	if  == nil {
		return "unknown method"
	}
	return .Name()
}
emptyInterface is the header for an interface{} value.
mustBeExported panics if f records that the value was obtained using an unexported field.
func ( flag) () {
	if  == 0 {
		panic(&ValueError{methodName(), 0})
	}
	if &flagRO != 0 {
		panic("reflect: " + methodName() + " using value obtained using unexported field")
	}
}
mustBeAssignable panics if f records that the value is not assignable, which is to say that either it was obtained using an unexported field or it is not addressable.
func ( flag) () {
	if  == 0 {
		panic(&ValueError{methodName(), Invalid})
Assignable if addressable and not read-only.
	if &flagRO != 0 {
		panic("reflect: " + methodName() + " using value obtained using unexported field")
	}
	if &flagAddr == 0 {
		panic("reflect: " + methodName() + " using unaddressable value")
	}
}
CanSet reports whether the value of v can be changed. A Value can be changed only if it is addressable and was not obtained by the use of unexported struct fields. If CanSet returns false, calling Set or any type-specific setter (e.g., SetBool, SetInt) will panic.
func ( Value) () bool {
	return .flag&(flagAddr|flagRO) == flagAddr
}
Elem returns the value that the interface v contains or that the pointer v points to. It panics if v's Kind is not Interface or Ptr. It returns the zero Value if v is nil.
func ( Value) () Value {
	 := .kind()
	switch  {
	case Interface:
		var  interface{}
		if .typ.NumMethod() == 0 {
			 = *(*interface{})(.ptr)
		} else {
			 = (interface{})(*(*interface {
				()
			})(.ptr))
		}
		 := unpackEface()
		if .flag != 0 {
			.flag |= .flag.ro()
		}
		return 
	case Ptr:
		 := .ptr
		if .flag&flagIndir != 0 {
			 = *(*unsafe.Pointer)()
The returned value's address is v's value.
		if  == nil {
			return Value{}
		}
		 := (*ptrType)(unsafe.Pointer(.typ))
		 := .elem
		 := .flag&flagRO | flagIndir | flagAddr
		 |= flag(.Kind())
		return Value{, , }
	}
	panic(&ValueError{"reflectlite.Value.Elem", .kind()})
}

func ( Value) interface{} {
	if .flag == 0 {
		panic(&ValueError{"reflectlite.Value.Interface", 0})
	}

Special case: return the element inside the interface. Empty interface has one layout, all interfaces with methods have a second layout.
		if .numMethod() == 0 {
			return *(*interface{})(.ptr)
		}
		return *(*interface {
			()
		})(.ptr)
	}
TODO: pass safe to packEface so we don't need to copy if safe==true?
	return packEface()
}
IsNil reports whether its argument v is nil. The argument must be a chan, func, interface, map, pointer, or slice value; if it is not, IsNil panics. Note that IsNil is not always equivalent to a regular comparison with nil in Go. For example, if v was created by calling ValueOf with an uninitialized interface variable i, i==nil will be true but v.IsNil will panic as v will be the zero Value.
func ( Value) () bool {
	 := .kind()
	switch  {
if v.flag&flagMethod != 0 { return false }
		 := .ptr
		if .flag&flagIndir != 0 {
			 = *(*unsafe.Pointer)()
		}
		return  == nil
Both interface and slice are nil if first word is 0. Both are always bigger than a word; assume flagIndir.
		return *(*unsafe.Pointer)(.ptr) == nil
	}
	panic(&ValueError{"reflectlite.Value.IsNil", .kind()})
}
IsValid reports whether v represents a value. It returns false if v is the zero Value. If IsValid returns false, all other methods except String panic. Most functions and methods never return an invalid Value. If one does, its documentation states the conditions explicitly.
func ( Value) () bool {
	return .flag != 0
}
Kind returns v's Kind. If v is the zero Value (IsValid returns false), Kind returns Invalid.
func ( Value) () Kind {
	return .kind()
}
implemented in runtime:
Len returns v's length. It panics if v's Kind is not Array, Chan, Map, Slice, or String.
func ( Value) () int {
	 := .kind()
	switch  {
	case Array:
		 := (*arrayType)(unsafe.Pointer(.typ))
		return int(.len)
	case Chan:
		return chanlen(.pointer())
	case Map:
		return maplen(.pointer())
Slice is bigger than a word; assume flagIndir.
		return (*unsafeheader.Slice)(.ptr).Len
String is bigger than a word; assume flagIndir.
		return (*unsafeheader.String)(.ptr).Len
	}
	panic(&ValueError{"reflect.Value.Len", .kind()})
}
NumMethod returns the number of exported methods in the value's method set.
func ( Value) () int {
	if .typ == nil {
		panic(&ValueError{"reflectlite.Value.NumMethod", Invalid})
	}
	return .typ.NumMethod()
}
Set assigns x to the value v. It panics if CanSet returns false. As in Go, x's value must be assignable to v's type.
func ( Value) ( Value) {
	.mustBeAssignable()
	.mustBeExported() // do not let unexported x leak
	var  unsafe.Pointer
	if .kind() == Interface {
		 = .ptr
	}
	 = .assignTo("reflectlite.Set", .typ, )
	if .flag&flagIndir != 0 {
		typedmemmove(.typ, .ptr, .ptr)
	} else {
		*(*unsafe.Pointer)(.ptr) = .ptr
	}
}
Type returns v's type.
func ( Value) () Type {
	 := .flag
	if  == 0 {
		panic(&ValueError{"reflectlite.Value.Type", Invalid})
Method values not supported.
	return .typ
}
* constructors
implemented in package runtime
ValueOf returns a new Value initialized to the concrete value stored in the interface i. ValueOf(nil) returns the zero Value.
func ( interface{}) Value {
	if  == nil {
		return Value{}
	}
TODO: Maybe allow contents of a Value to live on the stack. For now we make the contents always escape to the heap. It makes life easier in a few places (see chanrecv/mapassign comment below).
	escapes()

	return unpackEface()
}
assignTo returns a value v that can be assigned directly to typ. It panics if v is not assignable to typ. For a conversion to an interface type, target is a suggested scratch space to use.
if v.flag&flagMethod != 0 { v = makeMethodValue(context, v) }

	switch {
Overwrite type so that they match. Same memory layout, so no harm done.
		 := .flag&(flagAddr|flagIndir) | .flag.ro()
		 |= flag(.Kind())
		return Value{, .ptr, }

	case implements(, .typ):
		if  == nil {
			 = unsafe_New()
		}
A nil ReadWriter passed to nil Reader is OK, but using ifaceE2I below will panic. Avoid the panic by returning a nil dst (e.g., Reader) explicitly.
			return Value{, nil, flag(Interface)}
		}
		 := valueInterface()
		if .NumMethod() == 0 {
			*(*interface{})() = 
		} else {
			ifaceE2I(, , )
		}
		return Value{, , flagIndir | flag(Interface)}
	}
Failed.
	panic( + ": value of type " + .typ.String() + " is not assignable to type " + .String())
}
arrayAt returns the i-th element of p, an array whose elements are eltSize bytes wide. The array pointed at by p must have at least i+1 elements: it is invalid (but impossible to check here) to pass i >= len, because then the result will point outside the array. whySafe must explain why i < len. (Passing "i < len" is fine; the benefit is to surface this assumption at the call site.)
func ( unsafe.Pointer,  int,  uintptr,  string) unsafe.Pointer {
	return add(, uintptr()*, "i < len")
}

func ( *rtype,  interface{},  unsafe.Pointer)
typedmemmove copies a value of type t to dst from src.go:noescape
func ( *rtype, ,  unsafe.Pointer)
Dummy annotation marking that the value x escapes, for use in cases where the reflect code is so clever that the compiler cannot follow.
func ( interface{}) {
	if dummy.b {
		dummy.x = 
	}
}

var dummy struct {
	b bool
	x interface{}