// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2012 The Go Authors.  All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// +build appengine js

// This file contains an implementation of proto field accesses using package reflect.
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
// be used on App Engine.

package proto

import (
	"math"
	"reflect"
)

// A structPointer is a pointer to a struct.
type structPointer struct {
	v reflect.Value
}

// toStructPointer returns a structPointer equivalent to the given reflect value.
// The reflect value must itself be a pointer to a struct.
func toStructPointer(v reflect.Value) structPointer {
	return structPointer{v}
}

// IsNil reports whether p is nil.
func structPointer_IsNil(p structPointer) bool {
	return p.v.IsNil()
}

// Interface returns the struct pointer as an interface value.
func structPointer_Interface(p structPointer, _ reflect.Type) interface{} {
	return p.v.Interface()
}

// A field identifies a field in a struct, accessible from a structPointer.
// In this implementation, a field is identified by the sequence of field indices
// passed to reflect's FieldByIndex.
type field []int

// toField returns a field equivalent to the given reflect field.
func toField(f *reflect.StructField) field {
	return f.Index
}

// invalidField is an invalid field identifier.
var invalidField = field(nil)

// IsValid reports whether the field identifier is valid.
func (f field) IsValid() bool { return f != nil }

// field returns the given field in the struct as a reflect value.
func structPointer_field(p structPointer, f field) reflect.Value {
	// Special case: an extension map entry with a value of type T
	// passes a *T to the struct-handling code with a zero field,
	// expecting that it will be treated as equivalent to *struct{ X T },
	// which has the same memory layout. We have to handle that case
	// specially, because reflect will panic if we call FieldByIndex on a
	// non-struct.
	if f == nil {
		return p.v.Elem()
	}

	return p.v.Elem().FieldByIndex(f)
}

// ifield returns the given field in the struct as an interface value.
func structPointer_ifield(p structPointer, f field) interface{} {
	return structPointer_field(p, f).Addr().Interface()
}

// Bytes returns the address of a []byte field in the struct.
func structPointer_Bytes(p structPointer, f field) *[]byte {
	return structPointer_ifield(p, f).(*[]byte)
}

// BytesSlice returns the address of a [][]byte field in the struct.
func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
	return structPointer_ifield(p, f).(*[][]byte)
}

// Bool returns the address of a *bool field in the struct.
func structPointer_Bool(p structPointer, f field) **bool {
	return structPointer_ifield(p, f).(**bool)
}

// BoolVal returns the address of a bool field in the struct.
func structPointer_BoolVal(p structPointer, f field) *bool {
	return structPointer_ifield(p, f).(*bool)
}

// BoolSlice returns the address of a []bool field in the struct.
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
	return structPointer_ifield(p, f).(*[]bool)
}

// String returns the address of a *string field in the struct.
func structPointer_String(p structPointer, f field) **string {
	return structPointer_ifield(p, f).(**string)
}

// StringVal returns the address of a string field in the struct.
func structPointer_StringVal(p structPointer, f field) *string {
	return structPointer_ifield(p, f).(*string)
}

// StringSlice returns the address of a []string field in the struct.
func structPointer_StringSlice(p structPointer, f field) *[]string {
	return structPointer_ifield(p, f).(*[]string)
}

// Extensions returns the address of an extension map field in the struct.
func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
	return structPointer_ifield(p, f).(*XXX_InternalExtensions)
}

// ExtMap returns the address of an extension map field in the struct.
func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
	return structPointer_ifield(p, f).(*map[int32]Extension)
}

// NewAt returns the reflect.Value for a pointer to a field in the struct.
func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
	return structPointer_field(p, f).Addr()
}

// SetStructPointer writes a *struct field in the struct.
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
	structPointer_field(p, f).Set(q.v)
}

// GetStructPointer reads a *struct field in the struct.
func structPointer_GetStructPointer(p structPointer, f field) structPointer {
	return structPointer{structPointer_field(p, f)}
}

// StructPointerSlice the address of a []*struct field in the struct.
func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice {
	return structPointerSlice{structPointer_field(p, f)}
}

// A structPointerSlice represents the address of a slice of pointers to structs
// (themselves messages or groups). That is, v.Type() is *[]*struct{...}.
type structPointerSlice struct {
	v reflect.Value
}

func (p structPointerSlice) Len() int                  { return p.v.Len() }
func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} }
func (p structPointerSlice) Append(q structPointer) {
	p.v.Set(reflect.Append(p.v, q.v))
}

var (
	int32Type   = reflect.TypeOf(int32(0))
	uint32Type  = reflect.TypeOf(uint32(0))
	float32Type = reflect.TypeOf(float32(0))
	int64Type   = reflect.TypeOf(int64(0))
	uint64Type  = reflect.TypeOf(uint64(0))
	float64Type = reflect.TypeOf(float64(0))
)

// A word32 represents a field of type *int32, *uint32, *float32, or *enum.
// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable.
type word32 struct {
	v reflect.Value
}

// IsNil reports whether p is nil.
func word32_IsNil(p word32) bool {
	return p.v.IsNil()
}

// Set sets p to point at a newly allocated word with bits set to x.
func word32_Set(p word32, o *Buffer, x uint32) {
	t := p.v.Type().Elem()
	switch t {
	case int32Type:
		if len(o.int32s) == 0 {
			o.int32s = make([]int32, uint32PoolSize)
		}
		o.int32s[0] = int32(x)
		p.v.Set(reflect.ValueOf(&o.int32s[0]))
		o.int32s = o.int32s[1:]
		return
	case uint32Type:
		if len(o.uint32s) == 0 {
			o.uint32s = make([]uint32, uint32PoolSize)
		}
		o.uint32s[0] = x
		p.v.Set(reflect.ValueOf(&o.uint32s[0]))
		o.uint32s = o.uint32s[1:]
		return
	case float32Type:
		if len(o.float32s) == 0 {
			o.float32s = make([]float32, uint32PoolSize)
		}
		o.float32s[0] = math.Float32frombits(x)
		p.v.Set(reflect.ValueOf(&o.float32s[0]))
		o.float32s = o.float32s[1:]
		return
	}

	// must be enum
	p.v.Set(reflect.New(t))
	p.v.Elem().SetInt(int64(int32(x)))
}

// Get gets the bits pointed at by p, as a uint32.
func word32_Get(p word32) uint32 {
	elem := p.v.Elem()
	switch elem.Kind() {
	case reflect.Int32:
		return uint32(elem.Int())
	case reflect.Uint32:
		return uint32(elem.Uint())
	case reflect.Float32:
		return math.Float32bits(float32(elem.Float()))
	}
	panic("unreachable")
}

// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct.
func structPointer_Word32(p structPointer, f field) word32 {
	return word32{structPointer_field(p, f)}
}

// A word32Val represents a field of type int32, uint32, float32, or enum.
// That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
type word32Val struct {
	v reflect.Value
}

// Set sets *p to x.
func word32Val_Set(p word32Val, x uint32) {
	switch p.v.Type() {
	case int32Type:
		p.v.SetInt(int64(x))
		return
	case uint32Type:
		p.v.SetUint(uint64(x))
		return
	case float32Type:
		p.v.SetFloat(float64(math.Float32frombits(x)))
		return
	}

	// must be enum
	p.v.SetInt(int64(int32(x)))
}

// Get gets the bits pointed at by p, as a uint32.
func word32Val_Get(p word32Val) uint32 {
	elem := p.v
	switch elem.Kind() {
	case reflect.Int32:
		return uint32(elem.Int())
	case reflect.Uint32:
		return uint32(elem.Uint())
	case reflect.Float32:
		return math.Float32bits(float32(elem.Float()))
	}
	panic("unreachable")
}

// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
func structPointer_Word32Val(p structPointer, f field) word32Val {
	return word32Val{structPointer_field(p, f)}
}

// A word32Slice is a slice of 32-bit values.
// That is, v.Type() is []int32, []uint32, []float32, or []enum.
type word32Slice struct {
	v reflect.Value
}

func (p word32Slice) Append(x uint32) {
	n, m := p.v.Len(), p.v.Cap()
	if n < m {
		p.v.SetLen(n + 1)
	} else {
		t := p.v.Type().Elem()
		p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
	}
	elem := p.v.Index(n)
	switch elem.Kind() {
	case reflect.Int32:
		elem.SetInt(int64(int32(x)))
	case reflect.Uint32:
		elem.SetUint(uint64(x))
	case reflect.Float32:
		elem.SetFloat(float64(math.Float32frombits(x)))
	}
}

func (p word32Slice) Len() int {
	return p.v.Len()
}

func (p word32Slice) Index(i int) uint32 {
	elem := p.v.Index(i)
	switch elem.Kind() {
	case reflect.Int32:
		return uint32(elem.Int())
	case reflect.Uint32:
		return uint32(elem.Uint())
	case reflect.Float32:
		return math.Float32bits(float32(elem.Float()))
	}
	panic("unreachable")
}

// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct.
func structPointer_Word32Slice(p structPointer, f field) word32Slice {
	return word32Slice{structPointer_field(p, f)}
}

// word64 is like word32 but for 64-bit values.
type word64 struct {
	v reflect.Value
}

func word64_Set(p word64, o *Buffer, x uint64) {
	t := p.v.Type().Elem()
	switch t {
	case int64Type:
		if len(o.int64s) == 0 {
			o.int64s = make([]int64, uint64PoolSize)
		}
		o.int64s[0] = int64(x)
		p.v.Set(reflect.ValueOf(&o.int64s[0]))
		o.int64s = o.int64s[1:]
		return
	case uint64Type:
		if len(o.uint64s) == 0 {
			o.uint64s = make([]uint64, uint64PoolSize)
		}
		o.uint64s[0] = x
		p.v.Set(reflect.ValueOf(&o.uint64s[0]))
		o.uint64s = o.uint64s[1:]
		return
	case float64Type:
		if len(o.float64s) == 0 {
			o.float64s = make([]float64, uint64PoolSize)
		}
		o.float64s[0] = math.Float64frombits(x)
		p.v.Set(reflect.ValueOf(&o.float64s[0]))
		o.float64s = o.float64s[1:]
		return
	}
	panic("unreachable")
}

func word64_IsNil(p word64) bool {
	return p.v.IsNil()
}

func word64_Get(p word64) uint64 {
	elem := p.v.Elem()
	switch elem.Kind() {
	case reflect.Int64:
		return uint64(elem.Int())
	case reflect.Uint64:
		return elem.Uint()
	case reflect.Float64:
		return math.Float64bits(elem.Float())
	}
	panic("unreachable")
}

func structPointer_Word64(p structPointer, f field) word64 {
	return word64{structPointer_field(p, f)}
}

// word64Val is like word32Val but for 64-bit values.
type word64Val struct {
	v reflect.Value
}

func word64Val_Set(p word64Val, o *Buffer, x uint64) {
	switch p.v.Type() {
	case int64Type:
		p.v.SetInt(int64(x))
		return
	case uint64Type:
		p.v.SetUint(x)
		return
	case float64Type:
		p.v.SetFloat(math.Float64frombits(x))
		return
	}
	panic("unreachable")
}

func word64Val_Get(p word64Val) uint64 {
	elem := p.v
	switch elem.Kind() {
	case reflect.Int64:
		return uint64(elem.Int())
	case reflect.Uint64:
		return elem.Uint()
	case reflect.Float64:
		return math.Float64bits(elem.Float())
	}
	panic("unreachable")
}

func structPointer_Word64Val(p structPointer, f field) word64Val {
	return word64Val{structPointer_field(p, f)}
}

type word64Slice struct {
	v reflect.Value
}

func (p word64Slice) Append(x uint64) {
	n, m := p.v.Len(), p.v.Cap()
	if n < m {
		p.v.SetLen(n + 1)
	} else {
		t := p.v.Type().Elem()
		p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
	}
	elem := p.v.Index(n)
	switch elem.Kind() {
	case reflect.Int64:
		elem.SetInt(int64(int64(x)))
	case reflect.Uint64:
		elem.SetUint(uint64(x))
	case reflect.Float64:
		elem.SetFloat(float64(math.Float64frombits(x)))
	}
}

func (p word64Slice) Len() int {
	return p.v.Len()
}

func (p word64Slice) Index(i int) uint64 {
	elem := p.v.Index(i)
	switch elem.Kind() {
	case reflect.Int64:
		return uint64(elem.Int())
	case reflect.Uint64:
		return uint64(elem.Uint())
	case reflect.Float64:
		return math.Float64bits(float64(elem.Float()))
	}
	panic("unreachable")
}

func structPointer_Word64Slice(p structPointer, f field) word64Slice {
	return word64Slice{structPointer_field(p, f)}
}
