// Copyright 2018 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 protoreflect

import (
	"fmt"
	"math"
	"reflect"
)

// The protoreflect API uses a custom Value union type instead of interface{}
// to keep the future open for performance optimizations. Using an interface{}
// always incurs an allocation for primitives (e.g., int64) since it needs to
// be boxed on the heap (as interfaces can only contain pointers natively).
// Instead, we represent the Value union as a flat struct that internally keeps
// track of which type is set. Using unsafe, the Value union can be reduced
// down to 24B, which is identical in size to a slice.
//
// The latest compiler (Go1.11) currently suffers from some limitations:
//	• With inlining, the compiler should be able to statically prove that
//	only one of these switch cases are taken and inline one specific case.
//	See https://golang.org/issue/22310.

// ValueOf returns a Value initialized with the concrete value stored in v.
// This panics if the type does not match one of the allowed types in the
// Value union.
//
// After calling ValueOf on a []byte, the slice must no longer be mutated.
func ValueOf(v interface{}) Value {
	switch v := v.(type) {
	case nil:
		return Value{}
	case bool:
		if v {
			return Value{typ: boolType, num: 1}
		} else {
			return Value{typ: boolType, num: 0}
		}
	case int32:
		return Value{typ: int32Type, num: uint64(v)}
	case int64:
		return Value{typ: int64Type, num: uint64(v)}
	case uint32:
		return Value{typ: uint32Type, num: uint64(v)}
	case uint64:
		return Value{typ: uint64Type, num: uint64(v)}
	case float32:
		return Value{typ: float32Type, num: uint64(math.Float64bits(float64(v)))}
	case float64:
		return Value{typ: float64Type, num: uint64(math.Float64bits(float64(v)))}
	case string:
		return valueOfString(v)
	case []byte:
		return valueOfBytes(v[:len(v):len(v)])
	case EnumNumber:
		return Value{typ: enumType, num: uint64(v)}
	case Message, Vector, Map:
		return valueOfIface(v)
	default:
		// TODO: Special case ProtoEnum, ProtoMessage, *[]T, and *map[K]V?
		// Note: this would violate the documented invariant in Interface.
		panic(fmt.Sprintf("invalid type: %v", reflect.TypeOf(v)))
	}
}

// IsNull reports whether v is empty (has no value).
func (v Value) IsNull() bool {
	return v.typ == nilType
}

// Interface returns v as an interface{}.
// Returned []byte values must not be mutated.
//
// Invariant: v == ValueOf(v).Interface()
func (v Value) Interface() interface{} {
	switch v.typ {
	case nilType:
		return nil
	case boolType:
		return v.Bool()
	case int32Type:
		return int32(v.Int())
	case int64Type:
		return int64(v.Int())
	case uint32Type:
		return uint32(v.Uint())
	case uint64Type:
		return uint64(v.Uint())
	case float32Type:
		return float32(v.Float())
	case float64Type:
		return float64(v.Float())
	case stringType:
		return v.String()
	case bytesType:
		return v.Bytes()
	case enumType:
		return v.Enum()
	default:
		return v.getIface()
	}
}

// Bool returns v as a bool and panics if the type is not a bool.
func (v Value) Bool() bool {
	switch v.typ {
	case boolType:
		return v.num > 0
	default:
		panic("proto: value type mismatch")
	}
}

// Int returns v as a int64 and panics if the type is not a int32 or int64.
func (v Value) Int() int64 {
	switch v.typ {
	case int32Type, int64Type:
		return int64(v.num)
	default:
		panic("proto: value type mismatch")
	}
}

// Uint returns v as a uint64 and panics if the type is not a uint32 or uint64.
func (v Value) Uint() uint64 {
	switch v.typ {
	case uint32Type, uint64Type:
		return uint64(v.num)
	default:
		panic("proto: value type mismatch")
	}
}

// Float returns v as a float64 and panics if the type is not a float32 or float64.
func (v Value) Float() float64 {
	switch v.typ {
	case float32Type, float64Type:
		return math.Float64frombits(uint64(v.num))
	default:
		panic("proto: value type mismatch")
	}
}

// String returns v as a string. Since this method implements fmt.Stringer,
// this returns the formatted string value for any non-string type.
func (v Value) String() string {
	switch v.typ {
	case stringType:
		return v.getString()
	default:
		return fmt.Sprint(v.Interface())
	}
}

// Bytes returns v as a []byte and panics if the type is not a []byte.
// The returned slice must not be mutated.
func (v Value) Bytes() []byte {
	switch v.typ {
	case bytesType:
		return v.getBytes()
	default:
		panic("proto: value type mismatch")
	}
}

// Enum returns v as a EnumNumber and panics if the type is not a EnumNumber.
func (v Value) Enum() EnumNumber {
	switch v.typ {
	case enumType:
		return EnumNumber(v.num)
	default:
		panic("proto: value type mismatch")
	}
}

// Message returns v as a Message and panics if the type is not a Message.
func (v Value) Message() Message {
	switch v := v.getIface().(type) {
	case Message:
		return v
	default:
		panic("proto: value type mismatch")
	}
}

// Vector returns v as a Vector and panics if the type is not a Vector.
func (v Value) Vector() Vector {
	switch v := v.getIface().(type) {
	case Vector:
		return v
	default:
		panic("proto: value type mismatch")
	}
}

// Map returns v as a Map and panics if the type is not a Map.
func (v Value) Map() Map {
	switch v := v.getIface().(type) {
	case Map:
		return v
	default:
		panic("proto: value type mismatch")
	}
}

// MapKey returns v as a MapKey and panics for invalid MapKey types.
func (v Value) MapKey() MapKey {
	switch v.typ {
	case boolType, int32Type, int64Type, uint32Type, uint64Type, stringType:
		return MapKey(v)
	}
	panic("proto: invalid map key type")
}

// IsNull reports whether v is empty (has no value).
func (k MapKey) IsNull() bool {
	return Value(k).IsNull()
}

// Interface returns k as an interface{}.
func (k MapKey) Interface() interface{} {
	return Value(k).Interface()
}

// Bool returns k as a bool and panics if the type is not a bool.
func (k MapKey) Bool() bool {
	return Value(k).Bool()
}

// Int returns k as a int64 and panics if the type is not a int32 or int64.
func (k MapKey) Int() int64 {
	return Value(k).Int()
}

// Uint returns k as a uint64 and panics if the type is not a uint32 or uint64.
func (k MapKey) Uint() uint64 {
	return Value(k).Uint()
}

// String returns k as a string. Since this method implements fmt.Stringer,
// this returns the formatted string value for any non-string type.
func (k MapKey) String() string {
	return Value(k).String()
}

// Value returns k as a Value.
func (k MapKey) Value() Value {
	return Value(k)
}
