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

//go:build !purego && !appengine
// +build !purego,!appengine

package impl

import (
	
	
	
)

const UnsafeEnabled = true

// Pointer is an opaque pointer type.
type Pointer unsafe.Pointer

// offset represents the offset to a struct field, accessible from a pointer.
// The offset is the byte offset to the field from the start of the struct.
type offset uintptr

// offsetOf returns a field offset for the struct field.
func ( reflect.StructField,  exporter) offset {
	return offset(.Offset)
}

// IsValid reports whether the offset is valid.
func ( offset) () bool { return  != invalidOffset }

// invalidOffset is an invalid field offset.
var invalidOffset = ^offset(0)

// zeroOffset is a noop when calling pointer.Apply.
var zeroOffset = offset(0)

// pointer is a pointer to a message struct or field.
type pointer struct{ p unsafe.Pointer }

// pointerOf returns p as a pointer.
func ( Pointer) pointer {
	return pointer{p: unsafe.Pointer()}
}

// pointerOfValue returns v as a pointer.
func ( reflect.Value) pointer {
	return pointer{p: unsafe.Pointer(.Pointer())}
}

// pointerOfIface returns the pointer portion of an interface.
func ( interface{}) pointer {
	type  struct {
		 unsafe.Pointer
		 unsafe.Pointer
	}
	return pointer{p: (*)(unsafe.Pointer(&)).}
}

// IsNil reports whether the pointer is nil.
func ( pointer) () bool {
	return .p == nil
}

// Apply adds an offset to the pointer to derive a new pointer
// to a specified field. The pointer must be valid and pointing at a struct.
func ( pointer) ( offset) pointer {
	if .IsNil() {
		panic("invalid nil pointer")
	}
	return pointer{p: unsafe.Pointer(uintptr(.p) + uintptr())}
}

// AsValueOf treats p as a pointer to an object of type t and returns the value.
// It is equivalent to reflect.ValueOf(p.AsIfaceOf(t))
func ( pointer) ( reflect.Type) reflect.Value {
	return reflect.NewAt(, .p)
}

// AsIfaceOf treats p as a pointer to an object of type t and returns the value.
// It is equivalent to p.AsValueOf(t).Interface()
func ( pointer) ( reflect.Type) interface{} {
	// TODO: Use tricky unsafe magic to directly create ifaceHeader.
	return .AsValueOf().Interface()
}

func ( pointer) () *bool                           { return (*bool)(.p) }
func ( pointer) () **bool                       { return (**bool)(.p) }
func ( pointer) () *[]bool                    { return (*[]bool)(.p) }
func ( pointer) () *int32                         { return (*int32)(.p) }
func ( pointer) () **int32                     { return (**int32)(.p) }
func ( pointer) () *[]int32                  { return (*[]int32)(.p) }
func ( pointer) () *int64                         { return (*int64)(.p) }
func ( pointer) () **int64                     { return (**int64)(.p) }
func ( pointer) () *[]int64                  { return (*[]int64)(.p) }
func ( pointer) () *uint32                       { return (*uint32)(.p) }
func ( pointer) () **uint32                   { return (**uint32)(.p) }
func ( pointer) () *[]uint32                { return (*[]uint32)(.p) }
func ( pointer) () *uint64                       { return (*uint64)(.p) }
func ( pointer) () **uint64                   { return (**uint64)(.p) }
func ( pointer) () *[]uint64                { return (*[]uint64)(.p) }
func ( pointer) () *float32                     { return (*float32)(.p) }
func ( pointer) () **float32                 { return (**float32)(.p) }
func ( pointer) () *[]float32              { return (*[]float32)(.p) }
func ( pointer) () *float64                     { return (*float64)(.p) }
func ( pointer) () **float64                 { return (**float64)(.p) }
func ( pointer) () *[]float64              { return (*[]float64)(.p) }
func ( pointer) () *string                       { return (*string)(.p) }
func ( pointer) () **string                   { return (**string)(.p) }
func ( pointer) () *[]string                { return (*[]string)(.p) }
func ( pointer) () *[]byte                        { return (*[]byte)(.p) }
func ( pointer) () **[]byte                    { return (**[]byte)(.p) }
func ( pointer) () *[][]byte                 { return (*[][]byte)(.p) }
func ( pointer) () *weakFields               { return (*weakFields)(.p) }
func ( pointer) () *map[int32]ExtensionField { return (*map[int32]ExtensionField)(.p) }

func ( pointer) () pointer {
	return pointer{p: *(*unsafe.Pointer)(.p)}
}

// PointerSlice loads []*T from p as a []pointer.
// The value returned is aliased with the original slice.
// This behavior differs from the implementation in pointer_reflect.go.
func ( pointer) () []pointer {
	// Super-tricky - p should point to a []*T where T is a
	// message type. We load it as []pointer.
	return *(*[]pointer)(.p)
}

// AppendPointerSlice appends v to p, which must be a []*T.
func ( pointer) ( pointer) {
	*(*[]pointer)(.p) = append(*(*[]pointer)(.p), )
}

// SetPointer sets *p to v.
func ( pointer) ( pointer) {
	*(*unsafe.Pointer)(.p) = (unsafe.Pointer)(.p)
}

// Static check that MessageState does not exceed the size of a pointer.
const _ = uint(unsafe.Sizeof(unsafe.Pointer(nil)) - unsafe.Sizeof(MessageState{}))

func (Export) ( Pointer) *messageState {
	// Super-tricky - see documentation on MessageState.
	return (*messageState)(unsafe.Pointer())
}
func ( *messageState) () pointer {
	// Super-tricky - see documentation on MessageState.
	return pointer{p: unsafe.Pointer()}
}
func ( *messageState) () *MessageInfo {
	 := .LoadMessageInfo()
	if  == nil {
		panic("invalid nil message info; this suggests memory corruption due to a race or shallow copy on the message struct")
	}
	return 
}
func ( *messageState) () *MessageInfo {
	return (*MessageInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&.atomicMessageInfo))))
}
func ( *messageState) ( *MessageInfo) {
	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&.atomicMessageInfo)), unsafe.Pointer())
}

type atomicNilMessage struct{ p unsafe.Pointer } // p is a *messageReflectWrapper

func ( *atomicNilMessage) ( *MessageInfo) *messageReflectWrapper {
	if  := atomic.LoadPointer(&.p);  != nil {
		return (*messageReflectWrapper)()
	}
	 := &messageReflectWrapper{mi: }
	atomic.CompareAndSwapPointer(&.p, nil, (unsafe.Pointer)())
	return (*messageReflectWrapper)(atomic.LoadPointer(&.p))
}