// 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 reflect

import (
	"runtime";
	"strconv";
	"unsafe";
)

/*
 * Copy of data structures from ../runtime/type.go.
 * For comments, see the ones in that file.
 *
 * These data structures are known to the compiler and the runtime.
 *
 * Putting these types in runtime instead of reflect means that
 * reflect doesn't need to be autolinked into every binary, which
 * simplifies bootstrapping and package dependencies.
 * Unfortunately, it also means that reflect needs its own
 * copy in order to access the private fields.
 */

type commonType struct {
	size uintptr;
	hash uint32;
	alg uint8;
	align uint8;
	fieldAlign uint8;
	string *string;
	*uncommonType;
}

type method struct {
	hash uint32;
	name *string;
	pkgPath *string;
	typ *runtime.Type;
	ifn unsafe.Pointer;
	tfn unsafe.Pointer;
}

type uncommonType struct {
	name *string;
	pkgPath *string;
	methods []method;
}

// BoolType represents a boolean type.
type BoolType struct {
	commonType
}

// Float32Type represents a float32 type.
type Float32Type struct {
	commonType
}

// Float64Type represents a float64 type.
type Float64Type struct {
	commonType
}

// FloatType represents a float type.
type FloatType struct {
	commonType
}

// Int16Type represents an int16 type.
type Int16Type struct {
	commonType
}

// Int32Type represents an int32 type.
type Int32Type struct {
	commonType
}

// Int64Type represents an int64 type.
type Int64Type struct {
	commonType
}

// Int8Type represents an int8 type.
type Int8Type struct {
	commonType
}

// IntType represents an int type.
type IntType struct {
	commonType
}

// Uint16Type represents a uint16 type.
type Uint16Type struct {
	commonType
}

// Uint32Type represents a uint32 type.
type Uint32Type struct {
	commonType
}

// Uint64Type represents a uint64 type.
type Uint64Type struct {
	commonType
}

// Uint8Type represents a uint8 type.
type Uint8Type struct {
	commonType
}

// UintType represents a uint type.
type UintType struct {
	commonType
}

// StringType represents a string type.
type StringType struct {
	commonType
}

// UintptrType represents a uintptr type.
type UintptrType struct {
	commonType
}

// DotDotDotType represents the ... that can
// be used as the type of the final function parameter.
type DotDotDotType struct {
	commonType
}

// UnsafePointerType represents an unsafe.Pointer type.
type UnsafePointerType struct {
	commonType
}

// ArrayType represents a fixed array type.
type ArrayType struct {
	commonType;
	elem *runtime.Type;
	len uintptr;
}

// ChanDir represents a channel type's direction.
type ChanDir int
const (
	RecvDir ChanDir = 1<<iota;
	SendDir;
	BothDir = RecvDir | SendDir;
)

// ChanType represents a channel type.
type ChanType struct {
	commonType;
	elem *runtime.Type;
	dir uintptr;
}

// FuncType represents a function type.
type FuncType struct {
	commonType;
	in []*runtime.Type;
	out []*runtime.Type;
}

// Method on interface type
type imethod struct {
	hash uint32;
	perm uint32;
	name *string;
	pkgPath *string;
	typ *runtime.Type;
}

// InterfaceType represents an interface type.
type InterfaceType struct {
	commonType;
	methods []imethod;
}

// MapType represents a map type.
type MapType struct {
	commonType;
	key *runtime.Type;
	elem *runtime.Type;
}

// PtrType represents a pointer type.
type PtrType struct {
	commonType;
	elem *runtime.Type;
}

// SliceType represents a slice type.
type SliceType struct {
	commonType;
	elem *runtime.Type;
}

// Struct field
type structField struct {
	name *string;
	pkgPath *string;
	typ *runtime.Type;
	tag *string;
	offset uintptr;
}

// StructType represents a struct type.
type StructType struct {
	commonType;
	fields []structField;
}


/*
 * The compiler knows the exact layout of all the data structures above.
 * The compiler does not know about the data structures and methods below.
 */

// Method represents a single method.
type Method struct {
	PkgPath string;		// empty for uppercase Name
	Name string;
	Type *FuncType;
	Func *FuncValue;
}

// Type is the runtime representation of a Go type.
// Every type implements the methods listed here.
// Some types implement additional interfaces;
// use a type switch to find out what kind of type a Type is.
// Each type in a program has a unique Type, so == on Types
// corresponds to Go's type equality.
type Type interface {
	// PkgPath returns the type's package path.
	// The package path is a full package import path like "container/vector".
	PkgPath()	string;

	// Name returns the type's name within its package.
	Name()	string;

	// String returns a string representation of the type.
	// The string representation may use shortened package names
	// (e.g., vector instead of "container/vector") and is not
	// guaranteed to be unique among types.  To test for equality,
	// compare the Types directly.
	String()	string;

	// Size returns the number of bytes needed to store
	// a value of the given type; it is analogous to unsafe.Sizeof.
	Size()	uintptr;

	// Align returns the alignment of a value of this type
	// when allocated in memory.
	Align()	int;

	// FieldAlign returns the alignment of a value of this type
	// when used as a field in a struct.
	FieldAlign()	int;

	// For non-interface types, Method returns the i'th method with receiver T.
	// For interface types, Method returns the i'th method in the interface.
	// NumMethod returns the number of such methods.
	Method(int)	Method;
	NumMethod()	int;

	uncommon() *uncommonType;
}

func (t *uncommonType) uncommon() *uncommonType {
	return t;
}

func (t *uncommonType) PkgPath() string {
	if t == nil || t.pkgPath == nil {
		return ""
	}
	return *t.pkgPath;
}

func (t *uncommonType) Name() string {
	if t == nil || t.name == nil {
		return "";
	}
	return *t.name;
}

func (t *commonType) String() string {
	return *t.string;
}

func (t *commonType) Size() uintptr {
	return t.size;
}

func (t *commonType) Align() int {
	return int(t.align);
}

func (t *commonType) FieldAlign() int {
	return int(t.fieldAlign);
}

func (t *uncommonType) Method(i int) (m Method) {
	if t == nil || i < 0 || i >= len(t.methods) {
		return;
	}
	p := &t.methods[i];
	if p.name != nil {
		m.Name = *p.name;
	}
	if p.pkgPath != nil {
		m.PkgPath = *p.pkgPath;
	}
	m.Type = toType(*p.typ).(*FuncType);
	fn := p.tfn;
	m.Func = newFuncValue(m.Type, addr(&fn), true);
	return;
}

func (t *uncommonType) NumMethod() int {
	if t == nil {
		return 0;
	}
	return len(t.methods);
}

// TODO(rsc): 6g supplies these, but they are not
// as efficient as they could be: they have commonType
// as the receiver instead of *commonType.
func (t *commonType) NumMethod() int {
	return t.uncommonType.NumMethod();
}

func (t *commonType) Method(i int) (m Method) {
	return t.uncommonType.Method(i);
}

func (t *commonType) PkgPath() string {
	return t.uncommonType.PkgPath();
}

func (t *commonType) Name() string {
	return t.uncommonType.Name();
}

// Len returns the number of elements in the array.
func (t *ArrayType) Len() int {
	return int(t.len);
}

// Elem returns the type of the array's elements.
func (t *ArrayType) Elem() Type {
	return toType(*t.elem);
}

// Dir returns the channel direction.
func (t *ChanType) Dir() ChanDir {
	return ChanDir(t.dir);
}

// Elem returns the channel's element type.
func (t *ChanType) Elem() Type {
	return toType(*t.elem);
}

func (d ChanDir) String() string {
	switch d {
	case SendDir:
		return "chan<-";
	case RecvDir:
		return "<-chan";
	case BothDir:
		return "chan";
	}
	return "ChanDir" + strconv.Itoa(int(d));
}

// In returns the type of the i'th function input parameter.
func (t *FuncType) In(i int) Type {
	if i < 0 || i >= len(t.in) {
		return nil;
	}
	return toType(*t.in[i]);
}

// NumIn returns the number of input parameters.
func (t *FuncType) NumIn() int {
	return len(t.in);
}

// Out returns the type of the i'th function output parameter.
func (t *FuncType) Out(i int) Type {
	if i < 0 || i >= len(t.out) {
		return nil;
	}
	return toType(*t.out[i]);
}

// NumOut returns the number of function output parameters.
func (t *FuncType) NumOut() int {
	return len(t.out);
}

// Method returns the i'th interface method.
func (t *InterfaceType) Method(i int) (m Method) {
	if i < 0 || i >= len(t.methods) {
		return;
	}
	p := &t.methods[i];
	m.Name = *p.name;
	if p.pkgPath != nil {
		m.PkgPath = *p.pkgPath;
	}
	m.Type = toType(*p.typ).(*FuncType);
	return;
}

// NumMethod returns the number of interface methods.
func (t *InterfaceType) NumMethod() int {
	return len(t.methods);
}

// Key returns the map key type.
func (t *MapType) Key() Type {
	return toType(*t.key);
}

// Elem returns the map element type.
func (t *MapType) Elem() Type {
	return toType(*t.elem);
}

// Elem returns the pointer element type.
func (t *PtrType) Elem() Type {
	return toType(*t.elem);
}

// Elem returns the type of the slice's elements.
func (t *SliceType) Elem() Type {
	return toType(*t.elem);
}

type StructField struct {
	PkgPath string;		// empty for uppercase Name
	Name string;
	Type Type;
	Tag string;
	Offset uintptr;
	Index []int;
	Anonymous bool;
}

// Field returns the i'th struct field.
func (t *StructType) Field(i int) (f StructField) {
	if i < 0 || i >= len(t.fields) {
		return;
	}
	p := t.fields[i];
	f.Type = toType(*p.typ);
	if p.name != nil {
		f.Name = *p.name;
	} else {
		t := f.Type;
		if pt, ok := t.(*PtrType); ok {
			t = pt.Elem();
		}
		f.Name = t.Name();
		f.Anonymous = true;
	}
	if p.pkgPath != nil {
		f.PkgPath = *p.pkgPath;
	}
	if p.tag != nil {
		f.Tag = *p.tag;
	}
	f.Offset = p.offset;
	f.Index = []int{i};
	return;
}

// TODO(gri): Should there be an error/bool indicator if the index
//            is wrong for FieldByIndex?

// FieldByIndex returns the nested field corresponding to index.
func (t *StructType) FieldByIndex(index []int) (f StructField) {
	for i, x := range index {
		if i > 0 {
			ft := f.Type;
			if pt, ok := ft.(*PtrType); ok {
				ft = pt.Elem();
			}
			if st, ok := ft.(*StructType); ok {
				t = st;
			} else {
				var f0 StructField;
				f = f0;
				return;
			}
		}
		f = t.Field(x);
	}
	return;
}

const inf = 1 << 30;	// infinity - no struct has that many nesting levels

func (t *StructType) fieldByName(name string, mark map[*StructType]bool, depth int) (ff StructField, fd int) {
	fd = inf;	// field depth

	if _, marked := mark[t]; marked {
		// Struct already seen.
		return;
	}
	mark[t] = true;

	var fi int;	// field index
	n := 0;  // number of matching fields at depth fd
L:	for i, _ := range t.fields {
		f := t.Field(i);
		d := inf;
		switch {
		case f.Name == name:
			// Matching top-level field.
			d = depth;
		case f.Anonymous:
			ft := f.Type;
			if pt, ok := ft.(*PtrType); ok {
				ft = pt.Elem();
			}
			switch {
			case ft.Name() == name:
				// Matching anonymous top-level field.
				d = depth;
			case fd > depth:
				// No top-level field yet; look inside nested structs.
				if st, ok := ft.(*StructType); ok {
					f, d = st.fieldByName(name, mark, depth+1);
				}
			}
		}

		switch {
		case d < fd:
			// Found field at shallower depth.
			ff, fi, fd = f, i, d;
			n = 1;
		case d == fd:
			// More than one matching field at the same depth (or d, fd == inf).
			// Same as no field found at this depth.
			n++;
			if d == depth {
				// Impossible to find a field at lower depth.
				break L;
			}
		}
	}

	if n == 1 {
		// Found matching field.
		if len(ff.Index) <= depth {
			ff.Index = make([]int, depth+1);
		}
		ff.Index[depth] = fi;
	} else {
		// None or more than one matching field found.
		fd = inf;
	}

	mark[t] = false, false;
	return;
}

// FieldByName returns the struct field with the given name
// and a boolean to indicate if the field was found.
func (t *StructType) FieldByName(name string) (f StructField, present bool) {
	if ff, fd := t.fieldByName(name, make(map[*StructType]bool), 0); fd < inf {
		ff.Index = ff.Index[0 : fd+1];
		f, present = ff, true;
	}
	return
}

// NumField returns the number of struct fields.
func (t *StructType) NumField() int {
	return len(t.fields);
}

// Convert runtime type to reflect type.
// Same memory layouts, different method sets.
func toType(i interface{}) Type {
	switch v := i.(type) {
	case *runtime.BoolType:
		return (*BoolType)(unsafe.Pointer(v));
	case *runtime.DotDotDotType:
		return (*DotDotDotType)(unsafe.Pointer(v));
	case *runtime.FloatType:
		return (*FloatType)(unsafe.Pointer(v));
	case *runtime.Float32Type:
		return (*Float32Type)(unsafe.Pointer(v));
	case *runtime.Float64Type:
		return (*Float64Type)(unsafe.Pointer(v));
	case *runtime.IntType:
		return (*IntType)(unsafe.Pointer(v));
	case *runtime.Int8Type:
		return (*Int8Type)(unsafe.Pointer(v));
	case *runtime.Int16Type:
		return (*Int16Type)(unsafe.Pointer(v));
	case *runtime.Int32Type:
		return (*Int32Type)(unsafe.Pointer(v));
	case *runtime.Int64Type:
		return (*Int64Type)(unsafe.Pointer(v));
	case *runtime.StringType:
		return (*StringType)(unsafe.Pointer(v));
	case *runtime.UintType:
		return (*UintType)(unsafe.Pointer(v));
	case *runtime.Uint8Type:
		return (*Uint8Type)(unsafe.Pointer(v));
	case *runtime.Uint16Type:
		return (*Uint16Type)(unsafe.Pointer(v));
	case *runtime.Uint32Type:
		return (*Uint32Type)(unsafe.Pointer(v));
	case *runtime.Uint64Type:
		return (*Uint64Type)(unsafe.Pointer(v));
	case *runtime.UintptrType:
		return (*UintptrType)(unsafe.Pointer(v));
	case *runtime.UnsafePointerType:
		return (*UnsafePointerType)(unsafe.Pointer(v));
	case *runtime.ArrayType:
		return (*ArrayType)(unsafe.Pointer(v));
	case *runtime.ChanType:
		return (*ChanType)(unsafe.Pointer(v));
	case *runtime.FuncType:
		return (*FuncType)(unsafe.Pointer(v));
	case *runtime.InterfaceType:
		return (*InterfaceType)(unsafe.Pointer(v));
	case *runtime.MapType:
		return (*MapType)(unsafe.Pointer(v));
	case *runtime.PtrType:
		return (*PtrType)(unsafe.Pointer(v));
	case *runtime.SliceType:
		return (*SliceType)(unsafe.Pointer(v));
	case *runtime.StructType:
		return (*StructType)(unsafe.Pointer(v));
	}
	panicln("toType", i);
}

// ArrayOrSliceType is the common interface implemented
// by both ArrayType and SliceType.
type ArrayOrSliceType interface {
	Type;
	Elem() Type;
}

// Typeof returns the reflection Type of the value in the interface{}.
func Typeof(i interface{}) Type {
	return toType(unsafe.Typeof(i));
}


