// Copyright 2020, 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 value

import (
	
	
)

var anyType = reflect.TypeOf((*interface{})(nil)).Elem()

// TypeString is nearly identical to reflect.Type.String,
// but has an additional option to specify that full type names be used.
func ( reflect.Type,  bool) string {
	return string(appendTypeName(nil, , , false))
}

func ( []byte,  reflect.Type, ,  bool) []byte {
	// BUG: Go reflection provides no way to disambiguate two named types
	// of the same name and within the same package,
	// but declared within the namespace of different functions.

	// Use the "any" alias instead of "interface{}" for better readability.
	if  == anyType {
		return append(, "any"...)
	}

	// Named type.
	if .Name() != "" {
		if  && .PkgPath() != "" {
			 = append(, '"')
			 = append(, .PkgPath()...)
			 = append(, '"')
			 = append(, '.')
			 = append(, .Name()...)
		} else {
			 = append(, .String()...)
		}
		return 
	}

	// Unnamed type.
	switch  := .Kind();  {
	case reflect.Bool, reflect.String, reflect.UnsafePointer,
		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
		reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
		 = append(, .String()...)
	case reflect.Chan:
		if .ChanDir() == reflect.RecvDir {
			 = append(, "<-"...)
		}
		 = append(, "chan"...)
		if .ChanDir() == reflect.SendDir {
			 = append(, "<-"...)
		}
		 = append(, ' ')
		 = (, .Elem(), , false)
	case reflect.Func:
		if ! {
			 = append(, "func"...)
		}
		 = append(, '(')
		for  := 0;  < .NumIn(); ++ {
			if  > 0 {
				 = append(, ", "...)
			}
			if  == .NumIn()-1 && .IsVariadic() {
				 = append(, "..."...)
				 = (, .In().Elem(), , false)
			} else {
				 = (, .In(), , false)
			}
		}
		 = append(, ')')
		switch .NumOut() {
		case 0:
			// Do nothing
		case 1:
			 = append(, ' ')
			 = (, .Out(0), , false)
		default:
			 = append(, " ("...)
			for  := 0;  < .NumOut(); ++ {
				if  > 0 {
					 = append(, ", "...)
				}
				 = (, .Out(), , false)
			}
			 = append(, ')')
		}
	case reflect.Struct:
		 = append(, "struct{ "...)
		for  := 0;  < .NumField(); ++ {
			if  > 0 {
				 = append(, "; "...)
			}
			 := .Field()
			if !.Anonymous {
				if  && .PkgPath != "" {
					 = append(, '"')
					 = append(, .PkgPath...)
					 = append(, '"')
					 = append(, '.')
				}
				 = append(, .Name...)
				 = append(, ' ')
			}
			 = (, .Type, , false)
			if .Tag != "" {
				 = append(, ' ')
				 = strconv.AppendQuote(, string(.Tag))
			}
		}
		if [len()-1] == ' ' {
			 = [:len()-1]
		} else {
			 = append(, ' ')
		}
		 = append(, '}')
	case reflect.Slice, reflect.Array:
		 = append(, '[')
		if  == reflect.Array {
			 = strconv.AppendUint(, uint64(.Len()), 10)
		}
		 = append(, ']')
		 = (, .Elem(), , false)
	case reflect.Map:
		 = append(, "map["...)
		 = (, .Key(), , false)
		 = append(, ']')
		 = (, .Elem(), , false)
	case reflect.Ptr:
		 = append(, '*')
		 = (, .Elem(), , false)
	case reflect.Interface:
		 = append(, "interface{ "...)
		for  := 0;  < .NumMethod(); ++ {
			if  > 0 {
				 = append(, "; "...)
			}
			 := .Method()
			if  && .PkgPath != "" {
				 = append(, '"')
				 = append(, .PkgPath...)
				 = append(, '"')
				 = append(, '.')
			}
			 = append(, .Name...)
			 = (, .Type, , true)
		}
		if [len()-1] == ' ' {
			 = [:len()-1]
		} else {
			 = append(, ' ')
		}
		 = append(, '}')
	default:
		panic("invalid kind: " + .String())
	}
	return 
}