| 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), |
| ); |
| } |
| } |
| } |