// Copyright 2024 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 impl

import (
	"sync/atomic"
	"unsafe"
)

// presenceSize represents the size of a presence set, which should be the largest index of the set+1
type presenceSize uint32

// presence is the internal representation of the bitmap array in a generated protobuf
type presence struct {
	// This is a pointer to the beginning of an array of uint32
	P unsafe.Pointer
}

func (p presence) toElem(num uint32) (ret *uint32) {
	const (
		bitsPerByte = 8
		siz         = unsafe.Sizeof(*ret)
	)
	// p.P points to an array of uint32, num is the bit in this array that the
	// caller wants to check/manipulate. Calculate the index in the array that
	// contains this specific bit. E.g.: 76 / 32 = 2 (integer division).
	offset := uintptr(num) / (siz * bitsPerByte) * siz
	return (*uint32)(unsafe.Pointer(uintptr(p.P) + offset))
}

// Present checks for the presence of a specific field number in a presence set.
func (p presence) Present(num uint32) bool {
	if p.P == nil {
		return false
	}
	return Export{}.Present(p.toElem(num), num)
}

// SetPresent adds presence for a specific field number in a presence set.
func (p presence) SetPresent(num uint32, size presenceSize) {
	Export{}.SetPresent(p.toElem(num), num, uint32(size))
}

// SetPresentUnatomic adds presence for a specific field number in a presence set without using
// atomic operations. Only to be called during unmarshaling.
func (p presence) SetPresentUnatomic(num uint32, size presenceSize) {
	Export{}.SetPresentNonAtomic(p.toElem(num), num, uint32(size))
}

// ClearPresent removes presence for a specific field number in a presence set.
func (p presence) ClearPresent(num uint32) {
	Export{}.ClearPresent(p.toElem(num), num)
}

// LoadPresenceCache (together with PresentInCache) allows for a
// cached version of checking for presence without re-reading the word
// for every field. It is optimized for efficiency and assumes no
// simltaneous mutation of the presence set (or at least does not have
// a problem with simultaneous mutation giving inconsistent results).
func (p presence) LoadPresenceCache() (current uint32) {
	if p.P == nil {
		return 0
	}
	return atomic.LoadUint32((*uint32)(p.P))
}

// PresentInCache reads presence from a cached word in the presence
// bitmap. It caches up a new word if the bit is outside the
// word. This is for really fast iteration through bitmaps in cases
// where we either know that the bitmap will not be altered, or we
// don't care about inconsistencies caused by simultaneous writes.
func (p presence) PresentInCache(num uint32, cachedElement *uint32, current *uint32) bool {
	if num/32 != *cachedElement {
		o := uintptr(num/32) * unsafe.Sizeof(uint32(0))
		q := (*uint32)(unsafe.Pointer(uintptr(p.P) + o))
		*current = atomic.LoadUint32(q)
		*cachedElement = num / 32
	}
	return (*current & (1 << (num % 32))) > 0
}

// AnyPresent checks if any field is marked as present in the bitmap.
func (p presence) AnyPresent(size presenceSize) bool {
	n := uintptr((size + 31) / 32)
	for j := uintptr(0); j < n; j++ {
		o := j * unsafe.Sizeof(uint32(0))
		q := (*uint32)(unsafe.Pointer(uintptr(p.P) + o))
		b := atomic.LoadUint32(q)
		if b > 0 {
			return true
		}
	}
	return false
}

// toRaceDetectData finds the preceding RaceDetectHookData in a
// message by using pointer arithmetic. As the type of the presence
// set (bitmap) varies with the number of fields in the protobuf, we
// can not have a struct type containing the array and the
// RaceDetectHookData.  instead the RaceDetectHookData is placed
// immediately before the bitmap array, and we find it by walking
// backwards in the struct.
//
// This method is only called from the race-detect version of the code,
// so RaceDetectHookData is never an empty struct.
func (p presence) toRaceDetectData() *RaceDetectHookData {
	var template struct {
		d RaceDetectHookData
		a [1]uint32
	}
	o := (uintptr(unsafe.Pointer(&template.a)) - uintptr(unsafe.Pointer(&template.d)))
	return (*RaceDetectHookData)(unsafe.Pointer(uintptr(p.P) - o))
}

func atomicLoadShadowPresence(p **[]byte) *[]byte {
	return (*[]byte)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
}
func atomicStoreShadowPresence(p **[]byte, v *[]byte) {
	atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(p)), nil, unsafe.Pointer(v))
}

// findPointerToRaceDetectData finds the preceding RaceDetectHookData
// in a message by using pointer arithmetic. For the methods called
// directy from generated code, we don't have a pointer to the
// beginning of the presence set, but a pointer inside the array. As
// we know the index of the bit we're manipulating (num), we can
// calculate which element of the array ptr is pointing to. With that
// information we find the preceding RaceDetectHookData and can
// manipulate the shadow bitmap.
//
// This method is only called from the race-detect version of the
// code, so RaceDetectHookData is never an empty struct.
func findPointerToRaceDetectData(ptr *uint32, num uint32) *RaceDetectHookData {
	var template struct {
		d RaceDetectHookData
		a [1]uint32
	}
	o := (uintptr(unsafe.Pointer(&template.a)) - uintptr(unsafe.Pointer(&template.d))) + uintptr(num/32)*unsafe.Sizeof(uint32(0))
	return (*RaceDetectHookData)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) - o))
}
