use crate::__internal::Private;
use crate::__runtime::{
copy_bytes_in_arena_if_needed_by_runtime, InnerPrimitiveMut, MutatorMessageRef, PtrAndLen,
RawMessage,
};
use crate::{
AbsentField, FieldEntry, Mut, MutProxy, Optional, PresentField, PrimitiveMut, Proxied,
ProxiedWithPresence, View, ViewProxy,
};
use std::fmt::{self, Debug};
use std::marker::PhantomData;
use std::ptr::NonNull;
pub trait ProxiedWithRawVTable: Proxied {
type VTable: Debug + 'static;
fn make_view(_private: Private, mut_inner: RawVTableMutator<'_, Self>) -> View<'_, Self>;
fn make_mut(_private: Private, inner: RawVTableMutator<'_, Self>) -> Mut<'_, Self>;
}
pub trait ProxiedWithRawOptionalVTable: ProxiedWithRawVTable + ProxiedWithPresence {
type OptionalVTable: Debug + 'static;
fn upcast_vtable(
_private: Private,
optional_vtable: &'static Self::OptionalVTable,
) -> &'static Self::VTable;
}
#[doc(hidden)]
pub unsafe fn new_vtable_field_entry<'msg, T: ProxiedWithRawOptionalVTable + ?Sized>(
_private: Private,
msg_ref: MutatorMessageRef<'msg>,
optional_vtable: &'static T::OptionalVTable,
is_set: bool,
) -> FieldEntry<'msg, T>
where
T: ProxiedWithPresence<
PresentMutData<'msg> = RawVTableOptionalMutatorData<'msg, T>,
AbsentMutData<'msg> = RawVTableOptionalMutatorData<'msg, T>,
>,
{
let data = unsafe { RawVTableOptionalMutatorData::new(Private, msg_ref, optional_vtable) };
if is_set {
Optional::Set(PresentField::from_inner(Private, data))
} else {
Optional::Unset(AbsentField::from_inner(Private, data))
}
}
pub struct RawVTableMutator<'msg, T: ?Sized> {
msg_ref: MutatorMessageRef<'msg>,
vtable: NonNull<()>,
_phantom: PhantomData<&'msg T>,
}
impl<'msg, T: ?Sized> Clone for RawVTableMutator<'msg, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'msg, T: ?Sized> Copy for RawVTableMutator<'msg, T> {}
impl<'msg, T: ProxiedWithRawVTable + ?Sized> Debug for RawVTableMutator<'msg, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawVTableMutator")
.field("msg_ref", &self.msg_ref)
.field("vtable", self.vtable())
.finish()
}
}
impl<'msg, T: ProxiedWithRawVTable + ?Sized> RawVTableMutator<'msg, T> {
#[doc(hidden)]
pub unsafe fn new(
_private: Private,
msg_ref: MutatorMessageRef<'msg>,
vtable: &'static T::VTable,
) -> Self {
RawVTableMutator { msg_ref, vtable: NonNull::from(vtable).cast(), _phantom: PhantomData }
}
pub fn vtable(self) -> &'static T::VTable {
unsafe { self.vtable.cast().as_ref() }
}
pub fn msg_ref(self) -> MutatorMessageRef<'msg> {
self.msg_ref
}
}
pub struct RawVTableOptionalMutatorData<'msg, T: ?Sized> {
msg_ref: MutatorMessageRef<'msg>,
optional_vtable: NonNull<()>,
_phantom: PhantomData<&'msg T>,
}
unsafe impl<'msg, T: ?Sized> Sync for RawVTableOptionalMutatorData<'msg, T> {}
impl<'msg, T: ?Sized> Clone for RawVTableOptionalMutatorData<'msg, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'msg, T: ?Sized> Copy for RawVTableOptionalMutatorData<'msg, T> {}
impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> Debug
for RawVTableOptionalMutatorData<'msg, T>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawVTableOptionalMutatorData")
.field("msg_ref", &self.msg_ref)
.field("vtable", self.optional_vtable())
.finish()
}
}
impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized> RawVTableOptionalMutatorData<'msg, T> {
#[doc(hidden)]
pub unsafe fn new(
_private: Private,
msg_ref: MutatorMessageRef<'msg>,
vtable: &'static T::OptionalVTable,
) -> Self {
Self { msg_ref, optional_vtable: NonNull::from(vtable).cast(), _phantom: PhantomData }
}
pub fn msg_ref(self) -> MutatorMessageRef<'msg> {
self.msg_ref
}
pub fn optional_vtable(self) -> &'static T::OptionalVTable {
unsafe { self.optional_vtable.cast().as_ref() }
}
fn into_raw_mut(self) -> RawVTableMutator<'msg, T> {
unsafe {
RawVTableMutator::new(
Private,
self.msg_ref,
T::upcast_vtable(Private, self.optional_vtable()),
)
}
}
}
impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized + 'msg> ViewProxy<'msg>
for RawVTableOptionalMutatorData<'msg, T>
{
type Proxied = T;
fn as_view(&self) -> View<'_, T> {
T::make_view(Private, self.into_raw_mut())
}
fn into_view<'shorter>(self) -> View<'shorter, T>
where
'msg: 'shorter,
{
T::make_view(Private, self.into_raw_mut())
}
}
impl<'msg, T: ProxiedWithRawOptionalVTable + ?Sized + 'msg> MutProxy<'msg>
for RawVTableOptionalMutatorData<'msg, T>
{
fn as_mut(&mut self) -> Mut<'_, T> {
T::make_mut(Private, self.into_raw_mut())
}
fn into_mut<'shorter>(self) -> Mut<'shorter, T>
where
'msg: 'shorter,
{
T::make_mut(Private, self.into_raw_mut())
}
}
impl ProxiedWithRawVTable for [u8] {
type VTable = BytesMutVTable;
fn make_view(_private: Private, mut_inner: RawVTableMutator<'_, Self>) -> View<'_, Self> {
mut_inner.get()
}
fn make_mut(_private: Private, inner: RawVTableMutator<'_, Self>) -> Mut<'_, Self> {
crate::string::BytesMut::from_inner(Private, inner)
}
}
impl ProxiedWithRawOptionalVTable for [u8] {
type OptionalVTable = BytesOptionalMutVTable;
fn upcast_vtable(
_private: Private,
optional_vtable: &'static Self::OptionalVTable,
) -> &'static Self::VTable {
&optional_vtable.base
}
}
#[doc(hidden)]
#[derive(Debug)]
pub struct PrimitiveVTable<T> {
pub(crate) setter: unsafe extern "C" fn(msg: RawMessage, val: T),
pub(crate) getter: unsafe extern "C" fn(msg: RawMessage) -> T,
}
#[doc(hidden)]
#[derive(Debug)]
pub struct PrimitiveOptionalMutVTable<T> {
pub(crate) base: PrimitiveVTable<T>,
pub(crate) clearer: unsafe extern "C" fn(msg: RawMessage),
pub(crate) default: T,
}
impl<T> PrimitiveVTable<T> {
#[doc(hidden)]
pub const fn new(
_private: Private,
getter: unsafe extern "C" fn(msg: RawMessage) -> T,
setter: unsafe extern "C" fn(msg: RawMessage, val: T),
) -> Self {
Self { getter, setter }
}
}
impl<T> PrimitiveOptionalMutVTable<T> {
#[doc(hidden)]
pub const fn new(
_private: Private,
getter: unsafe extern "C" fn(msg: RawMessage) -> T,
setter: unsafe extern "C" fn(msg: RawMessage, val: T),
clearer: unsafe extern "C" fn(msg: RawMessage),
default: T,
) -> Self {
Self { base: PrimitiveVTable { getter, setter }, clearer, default }
}
}
#[doc(hidden)]
#[derive(Debug)]
pub struct BytesMutVTable {
pub(crate) setter: unsafe extern "C" fn(msg: RawMessage, val: PtrAndLen),
pub(crate) getter: unsafe extern "C" fn(msg: RawMessage) -> PtrAndLen,
}
#[derive(Debug)]
pub struct BytesOptionalMutVTable {
pub(crate) base: BytesMutVTable,
pub(crate) clearer: unsafe extern "C" fn(msg: RawMessage),
pub(crate) default: &'static [u8],
}
impl BytesMutVTable {
#[doc(hidden)]
pub const fn new(
_private: Private,
getter: unsafe extern "C" fn(msg: RawMessage) -> PtrAndLen,
setter: unsafe extern "C" fn(msg: RawMessage, val: PtrAndLen),
) -> Self {
Self { getter, setter }
}
}
impl BytesOptionalMutVTable {
#[doc(hidden)]
pub const unsafe fn new(
_private: Private,
getter: unsafe extern "C" fn(msg: RawMessage) -> PtrAndLen,
setter: unsafe extern "C" fn(msg: RawMessage, val: PtrAndLen),
clearer: unsafe extern "C" fn(msg: RawMessage),
default: &'static [u8],
) -> Self {
Self { base: BytesMutVTable { getter, setter }, clearer, default }
}
}
impl<'msg> RawVTableMutator<'msg, [u8]> {
pub(crate) fn get(self) -> &'msg [u8] {
unsafe { (self.vtable().getter)(self.msg_ref.msg()).as_ref() }
}
pub(crate) unsafe fn set(self, val: &[u8]) {
let val = copy_bytes_in_arena_if_needed_by_runtime(self.msg_ref, val);
unsafe { (self.vtable().setter)(self.msg_ref.msg(), val.into()) }
}
pub(crate) fn truncate(&self, len: usize) {
if len == 0 {
unsafe {
self.set(b"");
}
return;
}
todo!("b/294252563")
}
}
impl<'msg> RawVTableOptionalMutatorData<'msg, [u8]> {
pub(crate) fn set_absent_to_default(self) -> Self {
unsafe { self.set(self.optional_vtable().default) }
}
pub(crate) unsafe fn set(self, val: &[u8]) -> Self {
let val = copy_bytes_in_arena_if_needed_by_runtime(self.msg_ref, val);
unsafe { (self.optional_vtable().base.setter)(self.msg_ref.msg(), val.into()) }
self
}
pub(crate) fn clear(self) -> Self {
unsafe { (self.optional_vtable().clearer)(self.msg_ref.msg()) }
self
}
}
pub trait PrimitiveWithRawVTable:
Copy
+ Debug
+ 'static
+ ProxiedWithPresence
+ Sync
+ Send
+ for<'msg> Proxied<View<'msg> = Self, Mut<'msg> = PrimitiveMut<'msg, Self>>
{
}
impl<T: PrimitiveWithRawVTable> ProxiedWithRawVTable for T {
type VTable = PrimitiveVTable<T>;
fn make_view(_private: Private, mut_inner: InnerPrimitiveMut<'_, Self>) -> Self {
mut_inner.get()
}
fn make_mut(_private: Private, inner: InnerPrimitiveMut<'_, Self>) -> PrimitiveMut<'_, Self> {
unsafe { PrimitiveMut::from_inner(Private, inner) }
}
}
impl<T: PrimitiveWithRawVTable> ProxiedWithRawOptionalVTable for T {
type OptionalVTable = PrimitiveOptionalMutVTable<T>;
fn upcast_vtable(
_private: Private,
optional_vtable: &'static Self::OptionalVTable,
) -> &'static Self::VTable {
&optional_vtable.base
}
}
impl<T: PrimitiveWithRawVTable> RawVTableMutator<'_, T> {
pub(crate) fn get(self) -> T {
unsafe { (self.vtable().getter)(self.msg_ref.msg()) }
}
pub(crate) unsafe fn set(self, val: T) {
unsafe { (self.vtable().setter)(self.msg_ref.msg(), val) }
}
}
impl<'msg, T: PrimitiveWithRawVTable> RawVTableOptionalMutatorData<'msg, T> {
pub fn set_absent_to_default(self, private: Private) -> Self {
self.set(private, self.optional_vtable().default)
}
pub fn set(self, _private: Private, val: T) -> Self {
unsafe { (self.optional_vtable().base.setter)(self.msg_ref.msg(), val) }
self
}
pub fn clear(self, _private: Private) -> Self {
unsafe { (self.optional_vtable().clearer)(self.msg_ref.msg()) }
self
}
}