blob: 56ac7123e70c7252e2fa415727ad5e288f91950d [file] [log] [blame]
use super::*;
unsafe extern "C" {
pub fn proto2_rust_Message_delete(m: RawMessage);
pub fn proto2_rust_Message_clear(m: RawMessage);
pub fn proto2_rust_Message_parse(m: RawMessage, input: PtrAndLen) -> bool;
pub fn proto2_rust_Message_parse_dont_enforce_required(m: RawMessage, input: PtrAndLen)
-> bool;
pub fn proto2_rust_Message_serialize(m: RawMessage, output: &mut SerializedData) -> bool;
pub fn proto2_rust_Message_copy_from(dst: RawMessage, src: RawMessage);
pub fn proto2_rust_Message_merge_from(dst: RawMessage, src: RawMessage);
pub fn proto2_rust_Message_get_descriptor(m: RawMessage) -> *const std::ffi::c_void;
}
unsafe extern "C" {
/// From compare.h
///
/// # Safety
/// - `raw1` and `raw2` legally dereferenceable MessageLite* pointers.
#[link_name = "proto2_rust_messagelite_equals"]
pub fn raw_message_equals(raw1: RawMessage, raw2: RawMessage) -> bool;
}
#[derive(Debug)]
#[doc(hidden)]
#[repr(transparent)]
pub struct OwnedMessageInner<T> {
raw: RawMessage,
_phantom: PhantomData<T>,
}
impl<T: Message> OwnedMessageInner<T> {
/// # Safety
/// - `raw` must point to a message of type `T` and outlive `Self`.
pub unsafe fn wrap_raw(raw: RawMessage) -> Self {
OwnedMessageInner { raw, _phantom: PhantomData }
}
pub fn raw(&self) -> RawMessage {
self.raw
}
}
/// Mutators that point to their original message use this to do so.
///
/// Since C++ messages manage their own memory, this can just copy the
/// `RawMessage` instead of referencing an arena like UPB must.
///
/// Note: even though this type is `Copy`, it should only be copied by
/// protobuf internals that can maintain mutation invariants:
///
/// - No concurrent mutation for any two fields in a message: this means
/// mutators cannot be `Send` but are `Sync`.
/// - If there are multiple accessible `Mut` to a single message at a time, they
/// must be different fields, and not be in the same oneof. As such, a `Mut`
/// cannot be `Clone` but *can* reborrow itself with `.as_mut()`, which
/// converts `&'b mut Mut<'a, T>` to `Mut<'b, T>`.
#[derive(Debug)]
#[doc(hidden)]
#[repr(transparent)]
pub struct MessageMutInner<'msg, T> {
raw: RawMessage,
_phantom: PhantomData<(&'msg mut (), T)>,
}
impl<'msg, T: Message> Clone for MessageMutInner<'msg, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'msg, T: Message> Copy for MessageMutInner<'msg, T> {}
impl<'msg, T: Message> MessageMutInner<'msg, T> {
#[allow(clippy::needless_pass_by_ref_mut)] // Sound construction requires mutable access.
pub fn mut_of_owned(msg: &'msg mut OwnedMessageInner<T>) -> Self {
MessageMutInner { raw: msg.raw, _phantom: PhantomData }
}
/// # Safety
/// - The underlying pointer must be mutable, of type `T` and live for the lifetime 'msg.
pub unsafe fn wrap_raw(raw: RawMessage) -> Self {
MessageMutInner { raw, _phantom: PhantomData }
}
pub fn from_parent<ParentT: Message>(
_parent_msg: MessageMutInner<'msg, ParentT>,
message_field_ptr: RawMessage,
) -> Self {
Self { raw: message_field_ptr, _phantom: PhantomData }
}
pub fn raw(&self) -> RawMessage {
self.raw
}
}
#[derive(Debug)]
#[doc(hidden)]
#[repr(transparent)]
pub struct MessageViewInner<'msg, T> {
raw: RawMessage,
_phantom: PhantomData<(&'msg (), T)>,
}
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> {
/// # Safety
/// - The underlying pointer must of type `T` and live for the lifetime 'msg.
pub unsafe fn wrap_raw(raw: RawMessage) -> Self {
MessageViewInner { raw, _phantom: PhantomData }
}
pub fn view_of_owned(msg: &'msg OwnedMessageInner<T>) -> Self {
MessageViewInner { raw: msg.raw, _phantom: PhantomData }
}
pub fn view_of_mut(msg: MessageMutInner<'msg, T>) -> Self {
MessageViewInner { raw: msg.raw, _phantom: PhantomData }
}
pub fn raw(&self) -> RawMessage {
self.raw
}
}
/// Internal-only trait to support blanket impls that need const access to raw messages
/// on codegen. Should never be used by application code.
#[doc(hidden)]
pub unsafe trait CppGetRawMessage: SealedInternal {
fn get_raw_message(&self, _private: Private) -> RawMessage;
}
// The generated code only implements this trait on View proxies, so we use a blanket
// implementation for owned messages and Mut proxies.
unsafe impl<T> CppGetRawMessage for T
where
Self: AsMut + AsView,
for<'a> View<'a, <Self as AsView>::Proxied>: CppGetRawMessage,
{
fn get_raw_message(&self, _private: Private) -> RawMessage {
self.as_view().get_raw_message(_private)
}
}
/// Internal-only trait to support blanket impls that need mutable access to raw messages
/// on codegen. Must not be implemented on View proxies. Should never be used by application code.
#[doc(hidden)]
pub unsafe trait CppGetRawMessageMut: SealedInternal {
fn get_raw_message_mut(&mut self, _private: Private) -> RawMessage;
}
// The generated code only implements this trait on Mut proxies, so we use a blanket implementation
// for owned messages.
unsafe impl<T> CppGetRawMessageMut for T
where
Self: MutProxied,
for<'a> Mut<'a, Self>: CppGetRawMessageMut,
{
fn get_raw_message_mut(&mut self, _private: Private) -> RawMessage {
self.as_mut().get_raw_message_mut(_private)
}
}
pub trait KernelMessage: CppGetRawMessage + CppGetRawMessageMut {}
impl<T: CppGetRawMessage + CppGetRawMessageMut> KernelMessage for T {}
pub trait KernelMessageView: CppGetRawMessage {}
impl<T: CppGetRawMessage> KernelMessageView for T {}
pub trait KernelMessageMut: CppGetRawMessageMut {}
impl<T: CppGetRawMessageMut> KernelMessageMut for T {}
impl<'a, T> MessageMutInterop<'a> for T
where
Self: AsMut + CppGetRawMessageMut + From<MessageMutInner<'a, <Self as AsMut>::MutProxied>>,
<Self as AsMut>::MutProxied: Message,
{
unsafe fn __unstable_wrap_raw_message_mut(msg: &'a mut *mut std::ffi::c_void) -> Self {
let raw = RawMessage::new(*msg as *mut _).unwrap();
let inner = unsafe { MessageMutInner::wrap_raw(raw) };
inner.into()
}
unsafe fn __unstable_wrap_raw_message_mut_unchecked_lifetime(
msg: *mut std::ffi::c_void,
) -> Self {
let raw = RawMessage::new(msg as *mut _).unwrap();
let inner = unsafe { MessageMutInner::wrap_raw(raw) };
inner.into()
}
fn __unstable_as_raw_message_mut(&mut self) -> *mut std::ffi::c_void {
self.get_raw_message_mut(Private).as_ptr() as *mut _
}
}
/// Message equality definition which may have both false-negatives and false-positives in the face
/// of unknown fields.
///
/// This behavior is deliberately held back from being exposed as an `Eq` trait for messages. The
/// reason is that it is impossible to properly compare unknown fields for message equality, since
/// without the schema you cannot know how to interpret the wire format properly for comparison.
///
/// False negative cases (where message_eq will return false on unknown fields where it
/// would return true if the fields were known) are common and will occur in production: for
/// example, as map and repeated fields look exactly the same, map field order is unstable, the
/// comparison cannot know to treat it as unordered and will return false when it was the same
/// map but in a different order.
///
/// False positives cases (where message_eq will return true on unknown fields where it would have
/// return false if the fields were known) are possible but uncommon in practice. One example
/// of this direction can occur if two fields are defined in the same oneof and both are present on
/// the wire but in opposite order, without the schema these messages appear equal but with the
/// schema they are not-equal.
///
/// This lossy behavior in the face of unknown fields is especially problematic in the face of
/// extensions and other treeshaking behaviors where a given field being known or not to binary is a
/// spooky-action-at-a-distance behavior, which may lead to surprising changes in outcome in
/// equality tests based on changes made arbitrarily distant from the code performing the equality
/// check.
///
/// Broadly this is recommended for use in tests (where unknown field behaviors are rarely a
/// concern), and in limited/targeted cases where the lossy behavior in the face of unknown fields
/// behavior is unlikely to be a problem.
pub fn message_eq<T>(a: &T, b: &T) -> bool
where
T: AsView + Debug,
for<'a> View<'a, <T as AsView>::Proxied>: CppGetRawMessage,
{
unsafe {
raw_message_equals(
a.as_view().get_raw_message(Private),
b.as_view().get_raw_message(Private),
)
}
}
impl<T> MatcherEq for T
where
Self: AsView + Debug,
for<'a> View<'a, <Self as AsView>::Proxied>: CppGetRawMessage,
{
fn matches(&self, o: &Self) -> bool {
message_eq(self, o)
}
}
impl<T: CppGetRawMessageMut> Clear for T {
fn clear(&mut self) {
unsafe { proto2_rust_Message_clear(self.get_raw_message_mut(Private)) }
}
}
impl<T: CppGetRawMessageMut> ClearAndParse for T {
fn clear_and_parse(&mut self, data: &[u8]) -> Result<(), ParseError> {
unsafe { proto2_rust_Message_parse(self.get_raw_message_mut(Private), data.into()) }
.then_some(())
.ok_or(ParseError)
}
fn clear_and_parse_dont_enforce_required(&mut self, data: &[u8]) -> Result<(), ParseError> {
unsafe {
proto2_rust_Message_parse_dont_enforce_required(
self.get_raw_message_mut(Private),
data.into(),
)
}
.then_some(())
.ok_or(ParseError)
}
}
impl<T: CppGetRawMessage> Serialize for T {
fn serialize(&self) -> Result<Vec<u8>, SerializeError> {
let mut serialized_data = SerializedData::new();
let success = unsafe {
proto2_rust_Message_serialize(self.get_raw_message(Private), &mut serialized_data)
};
if success {
Ok(serialized_data.into_vec())
} else {
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();
// TODO: b/393559271 - Optimize this copy out.
CopyFrom::copy_from(self, AsView::as_view(&src));
Clear::clear(&mut src);
}
}
impl<T> CopyFrom for T
where
Self: AsMut,
for<'a> View<'a, Self::Proxied>: CppGetRawMessage,
for<'a> Mut<'a, Self::Proxied>: CppGetRawMessageMut,
{
fn copy_from(&mut self, src: impl AsView<Proxied = Self::Proxied>) {
unsafe {
proto2_rust_Message_copy_from(
self.as_mut().get_raw_message_mut(Private),
src.as_view().get_raw_message(Private),
);
}
}
}
impl<T> MergeFrom for T
where
Self: AsMut,
for<'a> View<'a, Self::Proxied>: CppGetRawMessage,
for<'a> Mut<'a, Self::Proxied>: CppGetRawMessageMut,
{
fn merge_from(&mut self, src: impl AsView<Proxied = Self::Proxied>) {
// SAFETY: self and src are both valid `T`s.
unsafe {
proto2_rust_Message_merge_from(
self.as_mut().get_raw_message_mut(Private),
src.as_view().get_raw_message(Private),
);
}
}
}