use super::*;
#[derive(Debug)]
#[doc(hidden)]
pub struct OwnedMessageInner<T> {
ptr: MessagePtr<T>,
arena: Arena,
}
impl<T: Message> Default for OwnedMessageInner<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Message> OwnedMessageInner<T> {
pub fn new() -> Self {
let arena = Arena::new();
let ptr = MessagePtr::new(&arena).expect("alloc should never fail");
Self { ptr, arena }
}
pub unsafe fn wrap_raw(raw: RawMessage, arena: Arena) -> Self {
let ptr = unsafe { MessagePtr::wrap(raw) };
OwnedMessageInner { ptr, arena }
}
pub fn ptr_mut(&mut self) -> MessagePtr<T> {
self.ptr
}
pub fn ptr(&self) -> MessagePtr<T> {
self.ptr
}
pub fn raw(&self) -> RawMessage {
self.ptr.raw()
}
#[allow(clippy::needless_pass_by_ref_mut)] pub fn arena(&mut self) -> &Arena {
&self.arena
}
}
#[derive(Debug)]
#[doc(hidden)]
pub struct MessageMutInner<'msg, T> {
pub(crate) ptr: MessagePtr<T>,
pub(crate) arena: &'msg Arena,
}
impl<'msg, T: Message> MessageMutInner<'msg, T> {
pub unsafe fn wrap_raw(raw: RawMessage, arena: &'msg Arena) -> Self {
let ptr = unsafe { MessagePtr::wrap(raw) };
MessageMutInner { ptr, arena }
}
#[allow(clippy::needless_pass_by_ref_mut)] pub fn mut_of_owned(msg: &'msg mut OwnedMessageInner<T>) -> Self {
MessageMutInner { ptr: msg.ptr, arena: &msg.arena }
}
pub fn from_parent<ParentT>(
parent_msg: MessageMutInner<'msg, ParentT>,
ptr: MessagePtr<T>,
) -> Self {
MessageMutInner { ptr, arena: parent_msg.arena }
}
pub fn ptr_mut(&mut self) -> MessagePtr<T> {
self.ptr
}
pub fn ptr(&self) -> MessagePtr<T> {
self.ptr
}
pub fn raw(&self) -> RawMessage {
self.ptr.raw()
}
pub fn arena(&self) -> &Arena {
self.arena
}
pub fn as_view(&self) -> MessageViewInner<'msg, T> {
MessageViewInner { ptr: self.ptr, _phantom: PhantomData }
}
pub fn reborrow<'shorter>(&mut self) -> MessageMutInner<'shorter, T>
where
'msg: 'shorter,
{
Self { ptr: self.ptr, arena: self.arena }
}
}
#[derive(Debug)]
#[doc(hidden)]
pub struct MessageViewInner<'msg, T> {
ptr: MessagePtr<T>,
_phantom: PhantomData<&'msg ()>,
}
impl<'msg, T: Message> Clone for MessageViewInner<'msg, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'msg, T: Message> Copy for MessageViewInner<'msg, T> {}
impl<'msg, T: Message> MessageViewInner<'msg, T> {
pub unsafe fn wrap(ptr: MessagePtr<T>) -> Self {
MessageViewInner { ptr, _phantom: PhantomData }
}
pub unsafe fn wrap_raw(raw: RawMessage) -> Self {
let ptr = unsafe { MessagePtr::wrap(raw) };
MessageViewInner { ptr, _phantom: PhantomData }
}
#[allow(clippy::needless_pass_by_ref_mut)] pub fn view_of_owned(owned: &'msg OwnedMessageInner<T>) -> Self {
MessageViewInner { ptr: owned.ptr, _phantom: PhantomData }
}
#[allow(clippy::needless_pass_by_ref_mut)] pub fn view_of_mut(msg_mut: MessageMutInner<'msg, T>) -> Self {
MessageViewInner { ptr: msg_mut.ptr, _phantom: PhantomData }
}
pub fn ptr(&self) -> MessagePtr<T> {
self.ptr
}
pub fn raw(&self) -> RawMessage {
self.ptr.raw()
}
}
const UPB_SCRATCH_SPACE_BYTES: usize = 65_536;
#[repr(C, align(8))] pub(crate) struct ScratchSpace([u8; UPB_SCRATCH_SPACE_BYTES]);
impl ScratchSpace {
pub fn zeroed_block() -> RawMessage {
static ZEROED_BLOCK: ScratchSpace = ScratchSpace([0; UPB_SCRATCH_SPACE_BYTES]);
NonNull::from(&ZEROED_BLOCK).cast()
}
}
impl<T: Message> Default for MessageViewInner<'static, T> {
fn default() -> Self {
unsafe {
Self::wrap_raw(ScratchSpace::zeroed_block())
}
}
}
#[doc(hidden)]
pub unsafe trait UpbGetMessagePtr: SealedInternal {
type Msg: AssociatedMiniTable + Message;
fn get_ptr(&self, _private: Private) -> MessagePtr<Self::Msg>;
}
#[doc(hidden)]
pub unsafe trait UpbGetMessagePtrMut: SealedInternal {
type Msg: AssociatedMiniTable + Message;
fn get_ptr_mut(&mut self, _private: Private) -> MessagePtr<Self::Msg>;
}
#[doc(hidden)]
pub unsafe trait UpbGetArena: SealedInternal {
fn get_arena(&mut self, _private: Private) -> &Arena;
}
pub trait KernelMessage:
AssociatedMiniTable + UpbGetArena + UpbGetMessagePtr + UpbGetMessagePtrMut + OwnedMessageInterop
{
}
impl<T> KernelMessage for T where
T: AssociatedMiniTable
+ UpbGetArena
+ UpbGetMessagePtr
+ UpbGetMessagePtrMut
+ OwnedMessageInterop
{
}
pub trait KernelMessageView<'msg>:
UpbGetMessagePtr + MessageViewInterop<'msg> + From<MessageViewInner<'msg, Self::KMessage>>
{
type KMessage;
}
impl<'msg, T> KernelMessageView<'msg> for T
where
T: UpbGetMessagePtr + MessageViewInterop<'msg> + From<MessageViewInner<'msg, T::Msg>>,
{
type KMessage = T::Msg;
}
pub trait KernelMessageMut<'msg>:
UpbGetMessagePtr
+ UpbGetMessagePtrMut
+ UpbGetArena
+ MessageMutInterop<'msg>
+ From<MessageMutInner<'msg, Self::KMessage>>
{
type KMessage;
}
impl<'msg, T> KernelMessageMut<'msg> for T
where
T: UpbGetMessagePtr
+ UpbGetMessagePtrMut
+ UpbGetArena
+ MessageMutInterop<'msg>
+ From<MessageMutInner<'msg, <T as UpbGetMessagePtr>::Msg>>,
{
type KMessage = <T as UpbGetMessagePtr>::Msg;
}
pub fn message_eq<T>(a: &T, b: &T) -> bool
where
T: AsView + Debug,
<T as AsView>::Proxied: AssociatedMiniTable,
for<'a> View<'a, <T as AsView>::Proxied>: UpbGetMessagePtr,
{
unsafe {
upb_Message_IsEqual(
a.as_view().get_ptr(Private).raw(),
b.as_view().get_ptr(Private).raw(),
<T as AsView>::Proxied::mini_table(),
0,
)
}
}
impl<T> MatcherEq for T
where
Self: AsView + Debug,
<Self as AsView>::Proxied: AssociatedMiniTable,
for<'a> View<'a, <Self as AsView>::Proxied>: UpbGetMessagePtr,
{
fn matches(&self, o: &Self) -> bool {
message_eq(self, o)
}
}
impl<T: UpbGetMessagePtrMut> Clear for T {
fn clear(&mut self) {
unsafe { self.get_ptr_mut(Private).clear() }
}
}
fn clear_and_parse_helper<T>(
msg: &mut T,
data: &[u8],
decode_options: i32,
) -> Result<(), ParseError>
where
T: UpbGetMessagePtrMut + UpbGetArena,
{
Clear::clear(msg);
unsafe {
upb::wire::decode_with_options(
data,
msg.get_ptr_mut(Private),
generated_extension_registry().as_ptr(),
msg.get_arena(Private),
decode_options,
)
}
.map(|_| ())
.map_err(|_| ParseError)
}
impl<T> ClearAndParse for T
where
Self: UpbGetMessagePtrMut + UpbGetArena,
{
fn clear_and_parse(&mut self, data: &[u8]) -> Result<(), ParseError> {
clear_and_parse_helper(self, data, upb::wire::decode_options::CHECK_REQUIRED)
}
fn clear_and_parse_dont_enforce_required(&mut self, data: &[u8]) -> Result<(), ParseError> {
clear_and_parse_helper(self, data, 0)
}
}
impl<T> Serialize for T
where
Self: UpbGetMessagePtr,
{
fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
upb::wire::encode(self.get_ptr(Private)).map_err(|_| SerializeError)
}
}
impl<T> TakeFrom for T
where
Self: CopyFrom + AsMut,
for<'a> Mut<'a, <Self as AsMut>::MutProxied>: Clear,
{
fn take_from(&mut self, mut src: impl AsMut<MutProxied = Self::Proxied>) {
let mut src = src.as_mut();
CopyFrom::copy_from(self, AsView::as_view(&src));
Clear::clear(&mut src);
}
}
impl<T> CopyFrom for T
where
Self: AsView + UpbGetArena + UpbGetMessagePtr,
Self::Proxied: AssociatedMiniTable,
for<'a> View<'a, Self::Proxied>: UpbGetMessagePtr,
{
fn copy_from(&mut self, src: impl AsView<Proxied = Self::Proxied>) {
unsafe {
assert!(upb_Message_DeepCopy(
self.get_ptr(Private).raw(),
src.as_view().get_ptr(Private).raw(),
<Self::Proxied as AssociatedMiniTable>::mini_table(),
self.get_arena(Private).raw()
));
}
}
}
impl<T> MergeFrom for T
where
Self: AsView + UpbGetArena + UpbGetMessagePtr,
Self::Proxied: AssociatedMiniTable,
for<'a> View<'a, Self::Proxied>: UpbGetMessagePtr,
{
fn merge_from(&mut self, src: impl AsView<Proxied = Self::Proxied>) {
unsafe {
assert!(upb_Message_MergeFrom(
self.get_ptr(Private).raw(),
src.as_view().get_ptr(Private).raw(),
<Self::Proxied as AssociatedMiniTable>::mini_table(),
generated_extension_registry().as_ptr(),
self.get_arena(Private).raw()
));
}
}
}
pub unsafe fn message_set_sub_message<
'msg,
P: Message + AssociatedMiniTable,
T: Message + UpbGetMessagePtrMut + UpbGetArena,
>(
parent: MessageMutInner<'msg, P>,
index: u32,
val: impl IntoProxied<T>,
) {
let mut child = val.into_proxied(Private);
parent.arena.fuse(child.get_arena(Private));
let child_ptr = child.get_ptr_mut(Private);
unsafe {
parent.ptr.set_base_field_message_at_index(index, child_ptr);
}
}
pub unsafe fn message_set_string_field<'msg, P: Message + AssociatedMiniTable>(
parent: MessageMutInner<'msg, P>,
index: u32,
val: impl IntoProxied<ProtoString>,
) {
let s = val.into_proxied(Private);
let (view, arena) = s.into_inner(Private).into_raw_parts();
parent.arena().fuse(&arena);
unsafe {
parent.ptr.set_base_field_string_at_index(index, view);
}
}
pub unsafe fn message_set_bytes_field<'msg, P: Message + AssociatedMiniTable>(
parent: MessageMutInner<'msg, P>,
index: u32,
val: impl IntoProxied<ProtoBytes>,
) {
let s = val.into_proxied(Private);
let (view, arena) = s.into_inner(Private).into_raw_parts();
parent.arena().fuse(&arena);
unsafe {
parent.ptr.set_base_field_string_at_index(index, view);
}
}
pub unsafe fn message_set_repeated_field<'msg, P: Message + AssociatedMiniTable, T: Singular>(
parent: MessageMutInner<'msg, P>,
index: u32,
val: impl IntoProxied<Repeated<T>>,
) {
let child = val.into_proxied(Private);
let inner = child.inner(Private);
parent.arena().fuse(inner.arena());
unsafe {
parent.ptr.set_array_at_index(index, inner.raw());
}
}
pub unsafe fn message_set_map_field<
'msg,
P: Message + AssociatedMiniTable,
K: MapKey,
V: MapValue,
>(
parent: MessageMutInner<'msg, P>,
index: u32,
val: impl IntoProxied<Map<K, V>>,
) {
let mut child = val.into_proxied(Private);
let child_as_mut = child.as_mut();
let mut inner = child_as_mut.inner(Private);
parent.arena().fuse(inner.arena());
unsafe {
parent.ptr.set_map_at_index(index, inner.as_raw());
}
}