mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
This change moves the `OwnedMessageInterop`, `MessageViewInterop`, and `MessageMutInterop` traits from `codegen_traits.rs` into new `interop.rs` files within both the `cpp_kernel` and `upb_kernel` directories. The `KernelMessage`, `KernelMessageView`, and `KernelMessageMut` traits in each kernel's `message.rs` are updated to include the respective kernel-specific interop traits. This ensures that the interop functionality is tied to the specific kernel implementation. The `shared.rs` module now re-exports the interop traits from `crate::__internal::runtime::interop`, which will resolve to the correct kernel's interop module. It would be possible to take this farther by making the interop traits return strongly typed pointers to `upb_Message*` and `proto2::MessageLite*` instead of `c_void`, but that would be a breaking change. PiperOrigin-RevId: 892470084
159 lines
6.9 KiB
Rust
159 lines
6.9 KiB
Rust
// Protocol Buffers - Google's data interchange format
|
|
// Copyright 2023 Google LLC. All rights reserved.
|
|
//
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file or at
|
|
// https://developers.google.com/open-source/licenses/bsd
|
|
|
|
//! Traits related to interop with the underlying C++ Proto types.
|
|
//!
|
|
//! These traits are deliberately not available on the prelude, as they should
|
|
//! be used rarely and with great care.
|
|
|
|
use super::*;
|
|
|
|
/// Methods for converting to and from a raw, owned C++ message pointer.
|
|
pub trait OwnedMessageInterop: SealedInternal {
|
|
/// Drops `self` and returns an underlying pointer that it was wrapping
|
|
/// without deleting it.
|
|
///
|
|
/// The caller is responsible for ensuring the returned pointer is
|
|
/// subsequently deleted (eg by moving it into a std::unique_ptr in
|
|
/// C++), or else it will leak.
|
|
fn __unstable_leak_raw_message(self) -> *mut std::ffi::c_void;
|
|
|
|
/// Takes exclusive ownership of the `raw_message`.
|
|
///
|
|
/// # Safety
|
|
/// - The underlying message must be for the same type as `Self`
|
|
/// - The pointer passed in must not be used by the caller after being
|
|
/// passed here (must not be read, written, or deleted)
|
|
unsafe fn __unstable_take_ownership_of_raw_message(raw_message: *mut std::ffi::c_void) -> Self;
|
|
}
|
|
|
|
/// Methods for converting to and from a raw C++ message view pointer.
|
|
pub trait MessageViewInterop<'msg>: SealedInternal {
|
|
/// Borrows `self` as an underlying C++ raw pointer.
|
|
///
|
|
/// Note that the returned Value must be used under the same constraints
|
|
/// as though it were a borrow of `self`: it should be treated as a
|
|
/// `const Message*` in C++, and not be mutated in any way, and any
|
|
/// mutation to the parent message may invalidate it, and it
|
|
/// must not be deleted.
|
|
fn __unstable_as_raw_message(&self) -> *const std::ffi::c_void;
|
|
|
|
/// Wraps the provided pointer as a MessageView.
|
|
///
|
|
/// This takes a ref of a pointer so that a stack variable's lifetime
|
|
/// can be used for a safe lifetime; under most cases this is
|
|
/// the correct lifetime and this should be used as:
|
|
/// ```ignore
|
|
/// fn called_from_cpp(msg: *const c_void) {
|
|
/// // `msg` is known live for the current stack frame, so view's
|
|
/// // lifetime is also tied to the current stack frame here:
|
|
/// let view = unsafe { __unstable_wrap_raw_message(&msg) };
|
|
/// do_something_with_view(view);
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// # Safety
|
|
/// - The underlying message must be for the same type as `Self`
|
|
/// - The underlying message must be alive for 'msg and not mutated
|
|
/// while the wrapper is live.
|
|
unsafe fn __unstable_wrap_raw_message(raw: &'msg *const std::ffi::c_void) -> Self;
|
|
|
|
/// Wraps the provided pointer as a MessageView.
|
|
///
|
|
/// Unlike `__unstable_wrap_raw_message` this has no constraints
|
|
/// on lifetime: the caller has a free choice for the lifetime.
|
|
///
|
|
/// As this is much easier to get the lifetime wrong than
|
|
/// `__unstable_wrap_raw_message`, prefer using that wherever
|
|
/// your lifetime can be tied to a stack lifetime, and only use this one
|
|
/// if its not possible (e.g. with a 'static lifetime).
|
|
///
|
|
/// # Safety
|
|
/// - The underlying message must be for the same type as `Self`
|
|
/// - The underlying message must be alive for the caller-chosen 'msg
|
|
/// and not mutated while the wrapper is live.
|
|
unsafe fn __unstable_wrap_raw_message_unchecked_lifetime(raw: *const std::ffi::c_void) -> Self;
|
|
}
|
|
|
|
/// Methods for converting to and from a raw, mutable C++ message pointer.
|
|
pub trait MessageMutInterop<'msg>: SealedInternal {
|
|
/// Exclusive borrows `self` as an underlying mutable C++ raw pointer.
|
|
///
|
|
/// Note that the returned Value must be used under the same constraints
|
|
/// as though it were a mut borrow of `self`: it should be treated as a
|
|
/// non-owned `Message*` in C++. And any mutation to the parent message
|
|
/// may invalidate it, and it must not be deleted.
|
|
fn __unstable_as_raw_message_mut(&mut self) -> *mut std::ffi::c_void;
|
|
|
|
/// Wraps the provided C++ pointer as a MessageMut.
|
|
///
|
|
/// This takes a ref of a pointer so that a stack variable's lifetime
|
|
/// can be used for a safe lifetime; under most cases this is
|
|
/// the correct lifetime and this should be used as:
|
|
/// ```ignore
|
|
/// fn called_from_cpp(msg: *mut c_void) {
|
|
/// // `msg` is known live for the current stack frame, so mut's
|
|
/// // lifetime is also tied to the current stack frame here:
|
|
/// let m = unsafe { __unstable_wrap_raw_message_mut(&mut msg) };
|
|
/// do_something_with_mut(m);
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// # Safety
|
|
/// - The underlying message must be for the same type as `Self`
|
|
/// - The underlying message must be alive for 'msg and not read or
|
|
/// mutated while the wrapper is live.
|
|
unsafe fn __unstable_wrap_raw_message_mut(raw: &'msg mut *mut std::ffi::c_void) -> Self;
|
|
|
|
/// Wraps the provided pointer as a MessageMut.
|
|
///
|
|
/// Unlike `__unstable_wrap_raw_message_mut` this has no constraints
|
|
/// on lifetime: the caller has a free choice for the lifetime.
|
|
///
|
|
/// As this is much easier to get the lifetime wrong than
|
|
/// `__unstable_wrap_raw_message_mut`, prefer using that wherever
|
|
/// the lifetime can be tied to a stack lifetime, and only use this one
|
|
/// if its not possible (e.g. with a 'static lifetime).
|
|
///
|
|
/// # Safety
|
|
/// - The underlying message must be for the same type as `Self`
|
|
/// - The underlying message must be alive for the caller-chosen 'msg
|
|
/// and not mutated while the wrapper is live.
|
|
unsafe fn __unstable_wrap_raw_message_mut_unchecked_lifetime(
|
|
raw: *mut std::ffi::c_void,
|
|
) -> Self;
|
|
}
|
|
|
|
/// Note that this is only implemented for the types implementing `proto2::Message`.
|
|
#[cfg(not(lite_runtime))]
|
|
pub trait MessageDescriptorInterop {
|
|
/// Returns a pointer to a `proto2::Descriptor` or `nullptr` if the
|
|
/// descriptor is not available.
|
|
fn __unstable_get_descriptor() -> *const std::ffi::c_void;
|
|
}
|
|
|
|
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 _
|
|
}
|
|
}
|