From 2678e10c99ca707f487b9fda81fef3f62fc433cc Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Fri, 12 Apr 2024 13:50:28 -0700 Subject: [PATCH] Create a upb rust directory. The intent of this directory would be for a layer of Rust bindings that directly map to upb semantics; Rust Protobuf runtime would be layer on top of that Rust, instead of directly on the upb C api. PiperOrigin-RevId: 624282429 --- rust/BUILD | 2 +- rust/cpp.rs | 109 +++++- rust/internal.rs | 127 +------ rust/map.rs | 4 +- rust/repeated.rs | 4 +- rust/string.rs | 6 +- rust/test/cpp/interop/main.rs | 2 +- rust/upb.rs | 263 +++----------- rust/upb/BUILD | 36 ++ rust/upb/README.md | 7 + rust/upb/shared.rs | 333 ++++++++++++++++++ rust/{upb_kernel => upb}/upb_api.c | 2 + rust/upb_kernel/BUILD | 15 - rust/vtable.rs | 5 +- .../protobuf/compiler/rust/accessors/map.cc | 12 +- .../compiler/rust/accessors/repeated_field.cc | 16 +- .../rust/accessors/singular_message.cc | 20 +- .../rust/accessors/singular_scalar.cc | 8 +- .../rust/accessors/singular_string.cc | 8 +- src/google/protobuf/compiler/rust/enum.cc | 18 +- src/google/protobuf/compiler/rust/message.cc | 74 ++-- src/google/protobuf/compiler/rust/naming.cc | 2 +- src/google/protobuf/compiler/rust/oneof.cc | 2 +- 23 files changed, 631 insertions(+), 444 deletions(-) create mode 100644 rust/upb/BUILD create mode 100644 rust/upb/README.md create mode 100644 rust/upb/shared.rs rename rust/{upb_kernel => upb}/upb_api.c (96%) delete mode 100644 rust/upb_kernel/BUILD diff --git a/rust/BUILD b/rust/BUILD index df5b8a3ba5..9bc42f3294 100644 --- a/rust/BUILD +++ b/rust/BUILD @@ -78,7 +78,7 @@ rust_library( ], deps = [ ":utf8", - "//rust/upb_kernel:upb_c_api", + "//rust/upb", ], ) diff --git a/rust/cpp.rs b/rust/cpp.rs index 93291135a5..225c97e519 100644 --- a/rust/cpp.rs +++ b/rust/cpp.rs @@ -7,15 +7,13 @@ // Rust Protobuf runtime using the C++ kernel. -use crate::__internal::{Enum, Private, PtrAndLen, RawMap, RawMessage, RawRepeatedField}; +use crate::__internal::{Enum, Private}; use crate::{ Map, MapIter, Mut, ProtoStr, Proxied, ProxiedInMapValue, ProxiedInRepeated, Repeated, RepeatedMut, RepeatedView, SettableValue, View, }; use core::fmt::Debug; use paste::paste; -use std::alloc::Layout; -use std::cell::UnsafeCell; use std::convert::identity; use std::ffi::{c_int, c_void}; use std::fmt; @@ -23,6 +21,111 @@ use std::marker::PhantomData; use std::mem::MaybeUninit; use std::ops::Deref; use std::ptr::{self, NonNull}; +use std::slice; + +/// Defines a set of opaque, unique, non-accessible pointees. +/// +/// The [Rustonomicon][nomicon] currently recommends a zero-sized struct, +/// though this should use [`extern type`] when that is stabilized. +/// [nomicon]: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs +/// [`extern type`]: https://github.com/rust-lang/rust/issues/43467 +mod _opaque_pointees { + /// Opaque pointee for [`RawMessage`] + /// + /// This type is not meant to be dereferenced in Rust code. + /// It is only meant to provide type safety for raw pointers + /// which are manipulated behind FFI. + /// + /// [`RawMessage`]: super::RawMessage + #[repr(C)] + pub struct RawMessageData { + _data: [u8; 0], + _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>, + } + + /// Opaque pointee for [`RawRepeatedField`] + /// + /// This type is not meant to be dereferenced in Rust code. + /// It is only meant to provide type safety for raw pointers + /// which are manipulated behind FFI. + #[repr(C)] + pub struct RawRepeatedFieldData { + _data: [u8; 0], + _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>, + } + + /// Opaque pointee for [`RawMap`] + /// + /// This type is not meant to be dereferenced in Rust code. + /// It is only meant to provide type safety for raw pointers + /// which are manipulated behind FFI. + #[repr(C)] + pub struct RawMapData { + _data: [u8; 0], + _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>, + } +} + +/// A raw pointer to the underlying message for this runtime. +pub type RawMessage = NonNull<_opaque_pointees::RawMessageData>; + +/// A raw pointer to the underlying repeated field container for this runtime. +pub type RawRepeatedField = NonNull<_opaque_pointees::RawRepeatedFieldData>; + +/// A raw pointer to the underlying arena for this runtime. +pub type RawMap = NonNull<_opaque_pointees::RawMapData>; + +/// Represents an ABI-stable version of `NonNull<[u8]>`/`string_view` (a +/// borrowed slice of bytes) for FFI use only. +/// +/// Has semantics similar to `std::string_view` in C++ and `&[u8]` in Rust, +/// but is not ABI-compatible with either. +/// +/// If `len` is 0, then `ptr` can be null or dangling. C++ considers a dangling +/// 0-len `std::string_view` to be invalid, and Rust considers a `&[u8]` with a +/// null data pointer to be invalid. +#[repr(C)] +#[derive(Copy, Clone)] +pub struct PtrAndLen { + /// Pointer to the first byte. + /// Borrows the memory. + pub ptr: *const u8, + + /// Length of the `[u8]` pointed to by `ptr`. + pub len: usize, +} + +impl PtrAndLen { + /// Unsafely dereference this slice. + /// + /// # Safety + /// - `self.ptr` must be dereferencable and immutable for `self.len` bytes + /// for the lifetime `'a`. It can be null or dangling if `self.len == 0`. + pub unsafe fn as_ref<'a>(self) -> &'a [u8] { + if self.ptr.is_null() { + assert_eq!(self.len, 0, "Non-empty slice with null data pointer"); + &[] + } else { + // SAFETY: + // - `ptr` is non-null + // - `ptr` is valid for `len` bytes as promised by the caller. + unsafe { slice::from_raw_parts(self.ptr, self.len) } + } + } +} + +impl From<&[u8]> for PtrAndLen { + fn from(slice: &[u8]) -> Self { + Self { ptr: slice.as_ptr(), len: slice.len() } + } +} + +impl From<&ProtoStr> for PtrAndLen { + fn from(s: &ProtoStr) -> Self { + let bytes = s.as_bytes(); + Self { ptr: bytes.as_ptr(), len: bytes.len() } + } +} /// Serialized Protobuf wire format data. It's typically produced by /// `.serialize()`. diff --git a/rust/internal.rs b/rust/internal.rs index b1b77db3bd..041c42d0da 100644 --- a/rust/internal.rs +++ b/rust/internal.rs @@ -16,128 +16,11 @@ pub use crate::vtable::{ RawVTableMutator, RawVTableOptionalMutatorData, }; pub use crate::ProtoStr; -use std::ptr::NonNull; -use std::slice; + +// TODO: Temporarily re-export these symbols which are now under +// __runtime under __internal since some external callers using it through +// __internal. +pub use crate::__runtime::{PtrAndLen, RawMap, RawMessage, RawRepeatedField}; /// Used to protect internal-only items from being used accidentally. pub struct Private; - -/// Defines a set of opaque, unique, non-accessible pointees. -/// -/// The [Rustonomicon][nomicon] currently recommends a zero-sized struct, -/// though this should use [`extern type`] when that is stabilized. -/// [nomicon]: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs -/// [`extern type`]: https://github.com/rust-lang/rust/issues/43467 -mod _opaque_pointees { - /// Opaque pointee for [`RawMessage`] - /// - /// This type is not meant to be dereferenced in Rust code. - /// It is only meant to provide type safety for raw pointers - /// which are manipulated behind FFI. - /// - /// [`RawMessage`]: super::RawMessage - #[repr(C)] - pub struct RawMessageData { - _data: [u8; 0], - _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>, - } - - /// Opaque pointee for [`RawArena`] - /// - /// This type is not meant to be dereferenced in Rust code. - /// It is only meant to provide type safety for raw pointers - /// which are manipulated behind FFI. - /// - /// [`RawArena`]: super::RawArena - #[repr(C)] - pub struct RawArenaData { - _data: [u8; 0], - _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>, - } - - /// Opaque pointee for [`RawRepeatedField`] - /// - /// This type is not meant to be dereferenced in Rust code. - /// It is only meant to provide type safety for raw pointers - /// which are manipulated behind FFI. - #[repr(C)] - pub struct RawRepeatedFieldData { - _data: [u8; 0], - _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>, - } - - /// Opaque pointee for [`RawMap`] - /// - /// This type is not meant to be dereferenced in Rust code. - /// It is only meant to provide type safety for raw pointers - /// which are manipulated behind FFI. - #[repr(C)] - pub struct RawMapData { - _data: [u8; 0], - _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>, - } -} - -/// A raw pointer to the underlying message for this runtime. -pub type RawMessage = NonNull<_opaque_pointees::RawMessageData>; - -/// A raw pointer to the underlying arena for this runtime. -pub type RawArena = NonNull<_opaque_pointees::RawArenaData>; - -/// A raw pointer to the underlying repeated field container for this runtime. -pub type RawRepeatedField = NonNull<_opaque_pointees::RawRepeatedFieldData>; - -/// A raw pointer to the underlying arena for this runtime. -pub type RawMap = NonNull<_opaque_pointees::RawMapData>; - -/// Represents an ABI-stable version of `NonNull<[u8]>`/`string_view` (a -/// borrowed slice of bytes) for FFI use only. -/// -/// Has semantics similar to `std::string_view` in C++ and `&[u8]` in Rust, -/// but is not ABI-compatible with either. -/// -/// If `len` is 0, then `ptr` can be null or dangling. C++ considers a dangling -/// 0-len `std::string_view` to be invalid, and Rust considers a `&[u8]` with a -/// null data pointer to be invalid. -#[repr(C)] -#[derive(Copy, Clone)] -pub struct PtrAndLen { - /// Pointer to the first byte. - /// Borrows the memory. - pub ptr: *const u8, - - /// Length of the `[u8]` pointed to by `ptr`. - pub len: usize, -} - -impl PtrAndLen { - /// Unsafely dereference this slice. - /// - /// # Safety - /// - `self.ptr` must be dereferencable and immutable for `self.len` bytes - /// for the lifetime `'a`. It can be null or dangling if `self.len == 0`. - pub unsafe fn as_ref<'a>(self) -> &'a [u8] { - if self.ptr.is_null() { - assert_eq!(self.len, 0, "Non-empty slice with null data pointer"); - &[] - } else { - // SAFETY: - // - `ptr` is non-null - // - `ptr` is valid for `len` bytes as promised by the caller. - unsafe { slice::from_raw_parts(self.ptr, self.len) } - } - } -} - -impl From<&[u8]> for PtrAndLen { - fn from(slice: &[u8]) -> Self { - Self { ptr: slice.as_ptr(), len: slice.len() } - } -} - -impl From<&ProtoStr> for PtrAndLen { - fn from(s: &ProtoStr) -> Self { - let bytes = s.as_bytes(); - Self { ptr: bytes.as_ptr(), len: bytes.len() } - } -} diff --git a/rust/map.rs b/rust/map.rs index 05285d098d..5ce74047b6 100644 --- a/rust/map.rs +++ b/rust/map.rs @@ -7,8 +7,8 @@ use crate::{ Mut, MutProxy, Proxied, SettableValue, View, ViewProxy, - __internal::{Private, RawMap}, - __runtime::{InnerMap, InnerMapMut, RawMapIter}, + __internal::Private, + __runtime::{InnerMap, InnerMapMut, RawMap, RawMapIter}, }; use std::marker::PhantomData; diff --git a/rust/repeated.rs b/rust/repeated.rs index 8c7c1cc8c3..068dd9a5ec 100644 --- a/rust/repeated.rs +++ b/rust/repeated.rs @@ -16,8 +16,8 @@ use std::marker::PhantomData; use crate::{ Mut, MutProxy, Proxied, SettableValue, View, ViewProxy, - __internal::{Private, RawRepeatedField}, - __runtime::{InnerRepeated, InnerRepeatedMut}, + __internal::Private, + __runtime::{InnerRepeated, InnerRepeatedMut, RawRepeatedField}, }; /// Views the elements in a `repeated` field of `T`. diff --git a/rust/string.rs b/rust/string.rs index d2b5a5d6e3..a6277d4b79 100644 --- a/rust/string.rs +++ b/rust/string.rs @@ -9,8 +9,10 @@ #![allow(dead_code)] #![allow(unused)] -use crate::__internal::{Private, PtrAndLen, RawMessage}; -use crate::__runtime::{BytesAbsentMutData, BytesPresentMutData, InnerBytesMut}; +use crate::__internal::Private; +use crate::__runtime::{ + BytesAbsentMutData, BytesPresentMutData, InnerBytesMut, PtrAndLen, RawMessage, +}; use crate::macros::impl_forwarding_settable_value; use crate::{ AbsentField, FieldEntry, Mut, MutProxy, Optional, PresentField, Proxied, ProxiedWithPresence, diff --git a/rust/test/cpp/interop/main.rs b/rust/test/cpp/interop/main.rs index 36c021cde8..f8e052795d 100644 --- a/rust/test/cpp/interop/main.rs +++ b/rust/test/cpp/interop/main.rs @@ -6,7 +6,7 @@ // https://developers.google.com/open-source/licenses/bsd use googletest::prelude::*; -use protobuf_cpp::__internal::{PtrAndLen, RawMessage}; +use protobuf_cpp::__runtime::{PtrAndLen, RawMessage}; use unittest_proto::{TestAllExtensions, TestAllTypes, TestAllTypesMut, TestAllTypesView}; macro_rules! proto_assert_eq { diff --git a/rust/upb.rs b/rust/upb.rs index ce57a48f8e..eec3cc12f8 100644 --- a/rust/upb.rs +++ b/rust/upb.rs @@ -7,7 +7,7 @@ //! UPB FFI wrapper code for use by Rust Protobuf. -use crate::__internal::{Enum, Private, PtrAndLen, RawArena, RawMap, RawMessage, RawRepeatedField}; +use crate::__internal::{Enum, Private}; use crate::{ Map, MapIter, MapMut, MapView, Mut, ProtoStr, Proxied, ProxiedInMapValue, ProxiedInRepeated, Repeated, RepeatedMut, RepeatedView, SettableValue, View, ViewProxy, @@ -16,7 +16,6 @@ use core::fmt::Debug; use std::alloc; use std::alloc::Layout; use std::cell::UnsafeCell; -use std::ffi::c_int; use std::fmt; use std::marker::PhantomData; use std::mem::{align_of, size_of, ManuallyDrop, MaybeUninit}; @@ -25,6 +24,25 @@ use std::ptr::{self, NonNull}; use std::slice; use std::sync::OnceLock; +extern crate upb; + +// Temporarily 'pub' since a lot of gencode is directly calling any of the ffi +// fns. +pub use upb::*; + +pub type RawArena = upb::RawArena; +pub type RawMessage = upb::RawMessage; +pub type RawRepeatedField = upb::RawArray; +pub type RawMap = upb::RawMap; +pub type PtrAndLen = upb::StringView; + +impl From<&ProtoStr> for PtrAndLen { + fn from(s: &ProtoStr) -> Self { + let bytes = s.as_bytes(); + Self { ptr: bytes.as_ptr(), len: bytes.len() } + } +} + /// See `upb/port/def.inc`. const UPB_MALLOC_ALIGN: usize = 8; const _CHECK_UPB_MALLOC_ALIGN_AT_LEAST_POINTER_ALIGNED: () = @@ -46,14 +64,6 @@ pub struct Arena { _not_sync: PhantomData>, } -extern "C" { - // `Option>` is ABI-compatible with `*mut T` - pub fn upb_Arena_New() -> Option; - pub fn upb_Arena_Free(arena: RawArena); - pub fn upb_Arena_Malloc(arena: RawArena, size: usize) -> *mut u8; - pub fn upb_Arena_Realloc(arena: RawArena, ptr: *mut u8, old: usize, new: usize) -> *mut u8; -} - impl Arena { /// Allocates a fresh arena. #[inline] @@ -332,89 +342,6 @@ fn copy_bytes_in_arena<'msg>(arena: &'msg Arena, val: &'msg [u8]) -> &'msg [u8] } } -// A macro for opaque pointees. -// This wrapper is a workaround until stabilization of [`extern type`]. -// TODO: convert to extern type once stabilized. -// [`extern type`]: https://github.com/rust-lang/rust/issues/43467 -macro_rules! opaque_pointee { - ($name:ident) => { - #[repr(C)] - pub struct $name { - _data: [u8; 0], - _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>, - } - }; -} - -// Opaque pointee for upb_MiniTable. -// TODO: consider importing a minitable struct declared in -// google3/third_party/upb/bits. -opaque_pointee!(OpaqueMiniTable); - -// Opaque pointee for upb_ExtensionRegistry -opaque_pointee!(OpaqueExtensionRegistry); - -extern "C" { - pub fn upb_Message_DeepCopy( - dst: RawMessage, - src: RawMessage, - mini_table: *const OpaqueMiniTable, - arena: RawArena, - ); - - pub fn upb_Message_DeepClone( - m: RawMessage, - mini_table: *const OpaqueMiniTable, - arena: RawArena, - ) -> Option; -} - -// LINT.IfChange(encode_status) -#[repr(C)] -#[derive(PartialEq, Eq, Copy, Clone)] -pub enum EncodeStatus { - Ok = 0, - OutOfMemory = 1, - MaxDepthExceeded = 2, - MissingRequired = 3, -} -// LINT.ThenChange() - -// LINT.IfChange(decode_status) -#[repr(C)] -#[derive(PartialEq, Eq, Copy, Clone)] -pub enum DecodeStatus { - Ok = 0, - Malformed = 1, - OutOfMemory = 2, - BadUtf8 = 3, - MaxDepthExceeded = 4, - MissingRequired = 5, - UnlinkedSubMessage = 6, -} -// LINT.ThenChange() - -extern "C" { - pub fn upb_Encode( - msg: RawMessage, - mini_table: *const OpaqueMiniTable, - options: i32, - arena: RawArena, - buf: *mut *mut u8, - buf_size: *mut usize, - ) -> EncodeStatus; - - pub fn upb_Decode( - buf: *const u8, - buf_size: usize, - msg: RawMessage, - mini_table: *const OpaqueMiniTable, - extreg: *const OpaqueExtensionRegistry, - options: i32, - arena: RawArena, - ) -> DecodeStatus; -} - /// The raw type-erased version of an owned `Repeated`. #[derive(Debug)] pub struct InnerRepeated { @@ -442,70 +369,13 @@ impl<'msg> InnerRepeatedMut<'msg> { } } -// Transcribed from google3/third_party/upb/upb/message/value.h -#[repr(C)] -#[derive(Clone, Copy)] -pub union upb_MessageValue { - pub bool_val: bool, - pub float_val: std::ffi::c_float, - pub double_val: std::ffi::c_double, - pub uint32_val: u32, - pub int32_val: i32, - pub uint64_val: u64, - pub int64_val: i64, - pub array_val: Option, - pub map_val: Option, - // TODO: Replace this `RawMessage` with the const type. - pub msg_val: Option, - pub str_val: PtrAndLen, - - tagged_msg_val: *const std::ffi::c_void, -} - -#[repr(C)] -#[derive(Clone, Copy)] -pub union upb_MutableMessageValue { - pub array: Option, - pub map: Option, - pub msg: Option, -} - -// Transcribed from google3/third_party/upb/upb/base/descriptor_constants.h -#[repr(C)] -#[allow(dead_code)] -pub enum UpbCType { - Bool = 1, - Float = 2, - Int32 = 3, - UInt32 = 4, - Enum = 5, - Message = 6, - Double = 7, - Int64 = 8, - UInt64 = 9, - String = 10, - Bytes = 11, -} - -extern "C" { - fn upb_Array_New(a: RawArena, r#type: std::ffi::c_int) -> RawRepeatedField; - pub fn upb_Array_Size(arr: RawRepeatedField) -> usize; - pub fn upb_Array_Set(arr: RawRepeatedField, i: usize, val: upb_MessageValue); - pub fn upb_Array_Get(arr: RawRepeatedField, i: usize) -> upb_MessageValue; - pub fn upb_Array_Append(arr: RawRepeatedField, val: upb_MessageValue, arena: RawArena); - pub fn upb_Array_Resize(arr: RawRepeatedField, size: usize, arena: RawArena) -> bool; - fn upb_Array_MutableDataPtr(arr: RawRepeatedField) -> *mut std::ffi::c_void; - fn upb_Array_DataPtr(arr: RawRepeatedField) -> *const std::ffi::c_void; - pub fn upb_Array_GetMutable(arr: RawRepeatedField, i: usize) -> upb_MutableMessageValue; -} - macro_rules! impl_repeated_base { ($t:ty, $elem_t:ty, $ufield:ident, $upb_tag:expr) => { #[allow(dead_code)] fn repeated_new(_: Private) -> Repeated<$t> { let arena = Arena::new(); Repeated::from_inner(InnerRepeated { - raw: unsafe { upb_Array_New(arena.raw(), $upb_tag as c_int) }, + raw: unsafe { upb_Array_New(arena.raw(), $upb_tag) }, arena, }) } @@ -519,11 +389,11 @@ macro_rules! impl_repeated_base { fn repeated_push(mut f: Mut>, v: View<$t>) { let arena = f.raw_arena(Private); unsafe { - upb_Array_Append( + assert!(upb_Array_Append( f.as_raw(Private), <$t as UpbTypeConversions>::to_message_value_copy_if_required(arena, v), arena, - ) + )); } } fn repeated_clear(mut f: Mut>) { @@ -624,17 +494,17 @@ impl<'msg, T: ?Sized> RepeatedMut<'msg, T> { } impl_repeated_primitives!( - // proxied type, element type, upb_MessageValue field name, UpbCType variant - (bool, bool, bool_val, UpbCType::Bool), - (f32, f32, float_val, UpbCType::Float), - (f64, f64, double_val, UpbCType::Double), - (i32, i32, int32_val, UpbCType::Int32), - (u32, u32, uint32_val, UpbCType::UInt32), - (i64, i64, int64_val, UpbCType::Int64), - (u64, u64, uint64_val, UpbCType::UInt64), + // proxied type, element type, upb_MessageValue field name, upb::CType variant + (bool, bool, bool_val, upb::CType::Bool), + (f32, f32, float_val, upb::CType::Float), + (f64, f64, double_val, upb::CType::Double), + (i32, i32, int32_val, upb::CType::Int32), + (u32, u32, uint32_val, upb::CType::UInt32), + (i64, i64, int64_val, upb::CType::Int64), + (u64, u64, uint64_val, upb::CType::UInt64), ); -impl_repeated_bytes!((ProtoStr, UpbCType::String), ([u8], UpbCType::Bytes),); +impl_repeated_bytes!((ProtoStr, upb::CType::String), ([u8], upb::CType::Bytes),); /// Copy the contents of `src` into `dest`. /// @@ -643,7 +513,7 @@ impl_repeated_bytes!((ProtoStr, UpbCType::String), ([u8], UpbCType::Bytes),); pub unsafe fn repeated_message_copy_from( src: View>, mut dest: Mut>, - minitable: *const OpaqueMiniTable, + minitable: *const upb_MiniTable, ) { // SAFETY: // - `src.as_raw()` is a valid `const upb_Array*`. @@ -801,7 +671,7 @@ impl<'msg> InnerMapMut<'msg> { } pub trait UpbTypeConversions: Proxied { - fn upb_type() -> UpbCType; + fn upb_type() -> upb::CType; fn to_message_value(val: View<'_, Self>) -> upb_MessageValue; /// # Safety @@ -822,7 +692,7 @@ macro_rules! impl_upb_type_conversions_for_scalars { $( impl UpbTypeConversions for $t { #[inline(always)] - fn upb_type() -> UpbCType { + fn upb_type() -> upb::CType { $upb_tag } @@ -846,18 +716,18 @@ macro_rules! impl_upb_type_conversions_for_scalars { } impl_upb_type_conversions_for_scalars!( - f32, float_val, UpbCType::Float, 0f32; - f64, double_val, UpbCType::Double, 0f64; - i32, int32_val, UpbCType::Int32, 0i32; - u32, uint32_val, UpbCType::UInt32, 0u32; - i64, int64_val, UpbCType::Int64, 0i64; - u64, uint64_val, UpbCType::UInt64, 0u64; - bool, bool_val, UpbCType::Bool, false; + f32, float_val, upb::CType::Float, 0f32; + f64, double_val, upb::CType::Double, 0f64; + i32, int32_val, upb::CType::Int32, 0i32; + u32, uint32_val, upb::CType::UInt32, 0u32; + i64, int64_val, upb::CType::Int64, 0i64; + u64, uint64_val, upb::CType::UInt64, 0u64; + bool, bool_val, upb::CType::Bool, false; ); impl UpbTypeConversions for [u8] { - fn upb_type() -> UpbCType { - UpbCType::Bytes + fn upb_type() -> upb::CType { + upb::CType::Bytes } fn to_message_value(val: View<'_, [u8]>) -> upb_MessageValue { @@ -881,8 +751,8 @@ impl UpbTypeConversions for [u8] { } impl UpbTypeConversions for ProtoStr { - fn upb_type() -> UpbCType { - UpbCType::String + fn upb_type() -> upb::CType { + upb::CType::String } fn to_message_value(val: View<'_, ProtoStr>) -> upb_MessageValue { @@ -1033,14 +903,6 @@ macro_rules! impl_ProxiedInMapValue_for_key_types { impl_ProxiedInMapValue_for_key_types!(i32, u32, i64, u64, bool, ProtoStr); -#[repr(C)] -#[allow(dead_code)] -pub enum upb_MapInsertStatus { - Inserted = 0, - Replaced = 1, - OutOfMemory = 2, -} - /// `upb_Map_Insert`, but returns a `bool` for whether insert occurred. /// /// Returns `true` if the entry was newly inserted. @@ -1061,39 +923,12 @@ pub unsafe fn upb_Map_InsertAndReturnIfInserted( arena: RawArena, ) -> bool { match unsafe { upb_Map_Insert(map, key, value, arena) } { - upb_MapInsertStatus::Inserted => true, - upb_MapInsertStatus::Replaced => false, - upb_MapInsertStatus::OutOfMemory => panic!("map arena is out of memory"), + upb::MapInsertStatus::Inserted => true, + upb::MapInsertStatus::Replaced => false, + upb::MapInsertStatus::OutOfMemory => panic!("map arena is out of memory"), } } -extern "C" { - pub fn upb_Map_New(arena: RawArena, key_type: UpbCType, value_type: UpbCType) -> RawMap; - pub fn upb_Map_Size(map: RawMap) -> usize; - pub fn upb_Map_Insert( - map: RawMap, - key: upb_MessageValue, - value: upb_MessageValue, - arena: RawArena, - ) -> upb_MapInsertStatus; - pub fn upb_Map_Get(map: RawMap, key: upb_MessageValue, value: *mut upb_MessageValue) -> bool; - pub fn upb_Map_Delete( - map: RawMap, - key: upb_MessageValue, - removed_value: *mut upb_MessageValue, - ) -> bool; - pub fn upb_Map_Clear(map: RawMap); - - static __rust_proto_kUpb_Map_Begin: usize; - - pub fn upb_Map_Next( - map: RawMap, - key: *mut upb_MessageValue, - value: *mut upb_MessageValue, - iter: &mut usize, - ) -> bool; -} - #[cfg(test)] mod tests { use super::*; diff --git a/rust/upb/BUILD b/rust/upb/BUILD new file mode 100644 index 0000000000..df43ce9f46 --- /dev/null +++ b/rust/upb/BUILD @@ -0,0 +1,36 @@ +# Copyright 2024 Google LLC +# +# 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 + +load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test") + +# begin:google_only +# package(default_applicable_licenses = ["//upb:license"]) +# end:google_only + +rust_library( + name = "upb", + srcs = ["shared.rs"], + visibility = [ + "//rust:__subpackages__", + "//src/google/protobuf:__subpackages__", + ], + deps = [":upb_c_api"], +) + +rust_test( + name = "upb_rs_crate_test", + crate = ":upb", +) + +cc_library( + name = "upb_c_api", + srcs = ["upb_api.c"], + deps = [ + "//upb:mem", + "//upb:message", + "//upb:message_copy", + ], +) diff --git a/rust/upb/README.md b/rust/upb/README.md new file mode 100644 index 0000000000..1e29faf879 --- /dev/null +++ b/rust/upb/README.md @@ -0,0 +1,7 @@ +# Rust upb bindings + +This directory contains Rust bindings for upb, attempting to be the a direct +mapping to expose upb to Rust. This should not be used directly by application +code, instead is an implementation detail for Rust Protobuf, which is still +under development but can be found here: +[here](https://github.com/protocolbuffers/protobuf/tree/main/rust). diff --git a/rust/upb/shared.rs b/rust/upb/shared.rs new file mode 100644 index 0000000000..b61028b5bc --- /dev/null +++ b/rust/upb/shared.rs @@ -0,0 +1,333 @@ +use std::ptr::NonNull; +use std::slice; + +// Macro to create structs that will act as opaque pointees. These structs are +// never intended to be dereferenced in Rust. +// This is a workaround until stabilization of [`extern type`]. +// TODO: convert to extern type once stabilized. +// [`extern type`]: https://github.com/rust-lang/rust/issues/43467 +macro_rules! opaque_pointee { + ($name: ident) => { + #[repr(C)] + pub struct $name { + _data: [u8; 0], + _marker: std::marker::PhantomData<(*mut u8, std::marker::PhantomPinned)>, + } + }; +} + +opaque_pointee!(upb_Arena); +pub type RawArena = NonNull; + +opaque_pointee!(upb_Message); +pub type RawMessage = NonNull; + +opaque_pointee!(upb_MiniTable); +pub type RawMiniTable = NonNull; + +opaque_pointee!(upb_ExtensionRegistry); +pub type RawExtensionRegistry = NonNull; + +opaque_pointee!(upb_Map); +pub type RawMap = NonNull; + +opaque_pointee!(upb_Array); +pub type RawArray = NonNull; + +extern "C" { + // `Option>` is ABI-compatible with `*mut T` + pub fn upb_Arena_New() -> Option; + pub fn upb_Arena_Free(arena: RawArena); + pub fn upb_Arena_Malloc(arena: RawArena, size: usize) -> *mut u8; + pub fn upb_Arena_Realloc(arena: RawArena, ptr: *mut u8, old: usize, new: usize) -> *mut u8; +} + +extern "C" { + pub fn upb_Message_DeepCopy( + dst: RawMessage, + src: RawMessage, + mini_table: *const upb_MiniTable, + arena: RawArena, + ); + + pub fn upb_Message_DeepClone( + m: RawMessage, + mini_table: *const upb_MiniTable, + arena: RawArena, + ) -> Option; +} + +// LINT.IfChange(encode_status) +#[repr(C)] +#[derive(PartialEq, Eq, Copy, Clone)] +pub enum EncodeStatus { + Ok = 0, + OutOfMemory = 1, + MaxDepthExceeded = 2, + MissingRequired = 3, +} +// LINT.ThenChange() + +// LINT.IfChange(decode_status) +#[repr(C)] +#[derive(PartialEq, Eq, Copy, Clone)] +pub enum DecodeStatus { + Ok = 0, + Malformed = 1, + OutOfMemory = 2, + BadUtf8 = 3, + MaxDepthExceeded = 4, + MissingRequired = 5, + UnlinkedSubMessage = 6, +} +// LINT.ThenChange() + +extern "C" { + pub fn upb_Encode( + msg: RawMessage, + mini_table: *const upb_MiniTable, + options: i32, + arena: RawArena, + buf: *mut *mut u8, + buf_size: *mut usize, + ) -> EncodeStatus; + + pub fn upb_Decode( + buf: *const u8, + buf_size: usize, + msg: RawMessage, + mini_table: *const upb_MiniTable, + extreg: *const upb_ExtensionRegistry, + options: i32, + arena: RawArena, + ) -> DecodeStatus; +} + +/// ABI compatible struct with upb_StringView. +/// +/// Note that this has semantics similar to `std::string_view` in C++ and +/// `&[u8]` in Rust, but is not ABI-compatible with either. +/// +/// If `len` is 0, then `ptr` is allowed to be either null or dangling. C++ +/// considers a dangling 0-len `std::string_view` to be invalid, and Rust +/// considers a `&[u8]` with a null data pointer to be invalid. +#[repr(C)] +#[derive(Copy, Clone)] +pub struct StringView { + /// Pointer to the first byte. + /// Borrows the memory. + pub ptr: *const u8, + + /// Length of the `[u8]` pointed to by `ptr`. + pub len: usize, +} + +impl StringView { + /// Unsafely dereference this slice. + /// + /// # Safety + /// - `self.ptr` must be dereferencable and immutable for `self.len` bytes + /// for the lifetime `'a`. It can be null or dangling if `self.len == 0`. + pub unsafe fn as_ref<'a>(self) -> &'a [u8] { + if self.ptr.is_null() { + assert_eq!(self.len, 0, "Non-empty slice with null data pointer"); + &[] + } else { + // SAFETY: + // - `ptr` is non-null + // - `ptr` is valid for `len` bytes as promised by the caller. + unsafe { slice::from_raw_parts(self.ptr, self.len) } + } + } +} + +impl From<&[u8]> for StringView { + fn from(slice: &[u8]) -> Self { + Self { ptr: slice.as_ptr(), len: slice.len() } + } +} + +// Transcribed from google3/third_party/upb/upb/message/value.h +#[repr(C)] +#[derive(Clone, Copy)] +pub union upb_MessageValue { + pub bool_val: bool, + pub float_val: std::ffi::c_float, + pub double_val: std::ffi::c_double, + pub uint32_val: u32, + pub int32_val: i32, + pub uint64_val: u64, + pub int64_val: i64, + // TODO: Replace this `RawMessage` with the const type. + pub array_val: Option, + pub map_val: Option, + pub msg_val: Option, + pub str_val: StringView, + + tagged_msg_val: *const std::ffi::c_void, +} + +impl upb_MessageValue { + pub fn zeroed() -> Self { + // SAFETY: zero bytes is a valid representation for at least one value in the + // union (actually valid for all of them). + unsafe { std::mem::zeroed() } + } +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub union upb_MutableMessageValue { + pub array: Option, + pub map: Option, + pub msg: Option, +} + +// Transcribed from google3/third_party/upb/upb/base/descriptor_constants.h +#[repr(C)] +#[allow(dead_code)] +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub enum CType { + Bool = 1, + Float = 2, + Int32 = 3, + UInt32 = 4, + Enum = 5, + Message = 6, + Double = 7, + Int64 = 8, + UInt64 = 9, + String = 10, + Bytes = 11, +} + +extern "C" { + pub fn upb_Array_New(a: RawArena, r#type: CType) -> RawArray; + pub fn upb_Array_Size(arr: RawArray) -> usize; + pub fn upb_Array_Set(arr: RawArray, i: usize, val: upb_MessageValue); + pub fn upb_Array_Get(arr: RawArray, i: usize) -> upb_MessageValue; + pub fn upb_Array_Append(arr: RawArray, val: upb_MessageValue, arena: RawArena) -> bool; + pub fn upb_Array_Resize(arr: RawArray, size: usize, arena: RawArena) -> bool; + pub fn upb_Array_MutableDataPtr(arr: RawArray) -> *mut std::ffi::c_void; + pub fn upb_Array_DataPtr(arr: RawArray) -> *const std::ffi::c_void; + pub fn upb_Array_GetMutable(arr: RawArray, i: usize) -> upb_MutableMessageValue; +} + +#[repr(C)] +#[allow(dead_code)] +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub enum MapInsertStatus { + Inserted = 0, + Replaced = 1, + OutOfMemory = 2, +} + +extern "C" { + pub fn upb_Map_New(arena: RawArena, key_type: CType, value_type: CType) -> RawMap; + pub fn upb_Map_Size(map: RawMap) -> usize; + pub fn upb_Map_Insert( + map: RawMap, + key: upb_MessageValue, + value: upb_MessageValue, + arena: RawArena, + ) -> MapInsertStatus; + pub fn upb_Map_Get(map: RawMap, key: upb_MessageValue, value: *mut upb_MessageValue) -> bool; + pub fn upb_Map_Delete( + map: RawMap, + key: upb_MessageValue, + removed_value: *mut upb_MessageValue, + ) -> bool; + pub fn upb_Map_Clear(map: RawMap); + + pub static __rust_proto_kUpb_Map_Begin: usize; + + pub fn upb_Map_Next( + map: RawMap, + key: *mut upb_MessageValue, + value: *mut upb_MessageValue, + iter: &mut usize, + ) -> bool; +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn arena_ffi_test() { + // SAFETY: FFI unit test uses C API under expected patterns. + unsafe { + let arena = upb_Arena_New().unwrap(); + let bytes = upb_Arena_Malloc(arena, 3); + let bytes = upb_Arena_Realloc(arena, bytes, 3, 512); + *bytes.add(511) = 7; + upb_Arena_Free(arena); + } + } + + #[test] + fn array_ffi_test() { + // SAFETY: FFI unit test uses C API under expected patterns. + unsafe { + let arena = upb_Arena_New().unwrap(); + let array = upb_Array_New(arena, CType::Float); + + assert!(upb_Array_Append(array, upb_MessageValue { float_val: 7.0 }, arena)); + assert!(upb_Array_Append(array, upb_MessageValue { float_val: 42.0 }, arena)); + assert_eq!(upb_Array_Size(array), 2); + assert!(matches!(upb_Array_Get(array, 1), upb_MessageValue { float_val: 42.0 })); + + assert!(upb_Array_Resize(array, 3, arena)); + assert_eq!(upb_Array_Size(array), 3); + assert!(matches!(upb_Array_Get(array, 2), upb_MessageValue { float_val: 0.0 })); + + upb_Arena_Free(arena); + } + } + + #[test] + fn map_ffi_test() { + // SAFETY: FFI unit test uses C API under expected patterns. + unsafe { + let arena = upb_Arena_New().unwrap(); + let map = upb_Map_New(arena, CType::Bool, CType::Double); + assert_eq!(upb_Map_Size(map), 0); + assert_eq!( + upb_Map_Insert( + map, + upb_MessageValue { bool_val: true }, + upb_MessageValue { double_val: 2.0 }, + arena + ), + MapInsertStatus::Inserted + ); + assert_eq!( + upb_Map_Insert( + map, + upb_MessageValue { bool_val: true }, + upb_MessageValue { double_val: 3.0 }, + arena, + ), + MapInsertStatus::Replaced, + ); + assert_eq!(upb_Map_Size(map), 1); + upb_Map_Clear(map); + assert_eq!(upb_Map_Size(map), 0); + assert_eq!( + upb_Map_Insert( + map, + upb_MessageValue { bool_val: true }, + upb_MessageValue { double_val: 4.0 }, + arena + ), + MapInsertStatus::Inserted + ); + + let mut out = upb_MessageValue::zeroed(); + assert!(upb_Map_Get(map, upb_MessageValue { bool_val: true }, &mut out)); + assert!(matches!(out, upb_MessageValue { double_val: 4.0 })); + + upb_Arena_Free(arena); + } + } +} diff --git a/rust/upb_kernel/upb_api.c b/rust/upb/upb_api.c similarity index 96% rename from rust/upb_kernel/upb_api.c rename to rust/upb/upb_api.c index 527d4b0810..6208be2464 100644 --- a/rust/upb_kernel/upb_api.c +++ b/rust/upb/upb_api.c @@ -6,6 +6,8 @@ // https://developers.google.com/open-source/licenses/bsd // +#include + #define UPB_BUILD_API #include "upb/mem/arena.h" // IWYU pragma: keep diff --git a/rust/upb_kernel/BUILD b/rust/upb_kernel/BUILD deleted file mode 100644 index c98774abb5..0000000000 --- a/rust/upb_kernel/BUILD +++ /dev/null @@ -1,15 +0,0 @@ -# This package contains Rust protobuf runtime implementation built on top of UPB. - -cc_library( - name = "upb_c_api", - srcs = ["upb_api.c"], - visibility = [ - "//rust:__subpackages__", - "//src/google/protobuf:__subpackages__", - ], - deps = [ - "//upb:mem", - "//upb:message", - "//upb:message_copy", - ], -) diff --git a/rust/vtable.rs b/rust/vtable.rs index 3e8802a329..52a0d87bc2 100644 --- a/rust/vtable.rs +++ b/rust/vtable.rs @@ -5,9 +5,10 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd -use crate::__internal::{Private, PtrAndLen, RawMessage}; +use crate::__internal::Private; use crate::__runtime::{ - copy_bytes_in_arena_if_needed_by_runtime, InnerPrimitiveMut, MutatorMessageRef, + copy_bytes_in_arena_if_needed_by_runtime, InnerPrimitiveMut, MutatorMessageRef, PtrAndLen, + RawMessage, }; use crate::{ AbsentField, FieldEntry, Mut, MutProxy, Optional, PresentField, PrimitiveMut, Proxied, diff --git a/src/google/protobuf/compiler/rust/accessors/map.cc b/src/google/protobuf/compiler/rust/accessors/map.cc index 3b963e506a..ee0d089784 100644 --- a/src/google/protobuf/compiler/rust/accessors/map.cc +++ b/src/google/protobuf/compiler/rust/accessors/map.cc @@ -114,15 +114,15 @@ void Map::InExternC(Context& ctx, const FieldDescriptor& field) const { [&] { if (ctx.is_upb()) { ctx.Emit({}, R"rs( - fn $getter_thunk$(raw_msg: $pbi$::RawMessage) - -> Option<$pbi$::RawMap>; - fn $getter_mut_thunk$(raw_msg: $pbi$::RawMessage, - arena: $pbi$::RawArena) -> $pbi$::RawMap; + fn $getter_thunk$(raw_msg: $pbr$::RawMessage) + -> Option<$pbr$::RawMap>; + fn $getter_mut_thunk$(raw_msg: $pbr$::RawMessage, + arena: $pbr$::RawArena) -> $pbr$::RawMap; )rs"); } else { ctx.Emit({}, R"rs( - fn $getter_thunk$(msg: $pbi$::RawMessage) -> $pbi$::RawMap; - fn $getter_mut_thunk$(msg: $pbi$::RawMessage,) -> $pbi$::RawMap; + fn $getter_thunk$(msg: $pbr$::RawMessage) -> $pbr$::RawMap; + fn $getter_mut_thunk$(msg: $pbr$::RawMessage,) -> $pbr$::RawMap; )rs"); } }}, diff --git a/src/google/protobuf/compiler/rust/accessors/repeated_field.cc b/src/google/protobuf/compiler/rust/accessors/repeated_field.cc index fce1df06ca..c48b437847 100644 --- a/src/google/protobuf/compiler/rust/accessors/repeated_field.cc +++ b/src/google/protobuf/compiler/rust/accessors/repeated_field.cc @@ -115,26 +115,26 @@ void RepeatedField::InExternC(Context& ctx, if (ctx.is_upb()) { ctx.Emit(R"rs( fn $getter_mut_thunk$( - raw_msg: $pbi$::RawMessage, + raw_msg: $pbr$::RawMessage, size: *const usize, - arena: $pbi$::RawArena, - ) -> $pbi$::RawRepeatedField; + arena: $pbr$::RawArena, + ) -> $pbr$::RawRepeatedField; // Returns `None` when returned array pointer is NULL. fn $getter_thunk$( - raw_msg: $pbi$::RawMessage, + raw_msg: $pbr$::RawMessage, size: *const usize, - ) -> Option<$pbi$::RawRepeatedField>; + ) -> Option<$pbr$::RawRepeatedField>; )rs"); } else { ctx.Emit(R"rs( - fn $getter_mut_thunk$(raw_msg: $pbi$::RawMessage) -> $pbi$::RawRepeatedField; - fn $getter_thunk$(raw_msg: $pbi$::RawMessage) -> $pbi$::RawRepeatedField; + fn $getter_mut_thunk$(raw_msg: $pbr$::RawMessage) -> $pbr$::RawRepeatedField; + fn $getter_thunk$(raw_msg: $pbr$::RawMessage) -> $pbr$::RawRepeatedField; )rs"); } }}, {"clearer_thunk", ThunkName(ctx, field, "clear")}}, R"rs( - fn $clearer_thunk$(raw_msg: $pbi$::RawMessage); + fn $clearer_thunk$(raw_msg: $pbr$::RawMessage); $getter$ )rs"); } diff --git a/src/google/protobuf/compiler/rust/accessors/singular_message.cc b/src/google/protobuf/compiler/rust/accessors/singular_message.cc index 179d48c25a..8f3ea9bfe0 100644 --- a/src/google/protobuf/compiler/rust/accessors/singular_message.cc +++ b/src/google/protobuf/compiler/rust/accessors/singular_message.cc @@ -161,32 +161,32 @@ void SingularMessage::InExternC(Context& ctx, if (ctx.is_cpp()) { ctx.Emit( R"rs( - fn $getter_mut_thunk$(raw_msg: $pbi$::RawMessage) - -> $pbi$::RawMessage;)rs"); + fn $getter_mut_thunk$(raw_msg: $pbr$::RawMessage) + -> $pbr$::RawMessage;)rs"); } else { ctx.Emit( - R"rs(fn $getter_mut_thunk$(raw_msg: $pbi$::RawMessage, - arena: $pbi$::RawArena) - -> $pbi$::RawMessage;)rs"); + R"rs(fn $getter_mut_thunk$(raw_msg: $pbr$::RawMessage, + arena: $pbr$::RawArena) + -> $pbr$::RawMessage;)rs"); } }}, {"ReturnType", [&] { if (ctx.is_cpp()) { // guaranteed to have a nonnull submsg for the cpp kernel - ctx.Emit({}, "$pbi$::RawMessage;"); + ctx.Emit({}, "$pbr$::RawMessage;"); } else { // upb kernel may return NULL for a submsg, we can detect this // in terra rust if the option returned is None - ctx.Emit({}, "Option<$pbi$::RawMessage>;"); + ctx.Emit({}, "Option<$pbr$::RawMessage>;"); } }}, }, R"rs( - fn $getter_thunk$(raw_msg: $pbi$::RawMessage) -> $ReturnType$; + fn $getter_thunk$(raw_msg: $pbr$::RawMessage) -> $ReturnType$; $getter_mut$ - fn $clearer_thunk$(raw_msg: $pbi$::RawMessage); - fn $hazzer_thunk$(raw_msg: $pbi$::RawMessage) -> bool; + fn $clearer_thunk$(raw_msg: $pbr$::RawMessage); + fn $hazzer_thunk$(raw_msg: $pbr$::RawMessage) -> bool; )rs"); } diff --git a/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc b/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc index da12ec585a..bf8bf622d3 100644 --- a/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc +++ b/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc @@ -109,15 +109,15 @@ void SingularScalar::InExternC(Context& ctx, [&] { if (field.has_presence()) { ctx.Emit(R"rs( - fn $hazzer_thunk$(raw_msg: $pbi$::RawMessage) -> bool; - fn $clearer_thunk$(raw_msg: $pbi$::RawMessage); + fn $hazzer_thunk$(raw_msg: $pbr$::RawMessage) -> bool; + fn $clearer_thunk$(raw_msg: $pbr$::RawMessage); )rs"); } }}}, R"rs( $with_presence_fields_thunks$ - fn $getter_thunk$(raw_msg: $pbi$::RawMessage) -> $Scalar$; - fn $setter_thunk$(raw_msg: $pbi$::RawMessage, val: $Scalar$); + fn $getter_thunk$(raw_msg: $pbr$::RawMessage) -> $Scalar$; + fn $setter_thunk$(raw_msg: $pbr$::RawMessage, val: $Scalar$); )rs"); } diff --git a/src/google/protobuf/compiler/rust/accessors/singular_string.cc b/src/google/protobuf/compiler/rust/accessors/singular_string.cc index 9328e7b827..afb3592e75 100644 --- a/src/google/protobuf/compiler/rust/accessors/singular_string.cc +++ b/src/google/protobuf/compiler/rust/accessors/singular_string.cc @@ -194,15 +194,15 @@ void SingularString::InExternC(Context& ctx, [&] { if (field.has_presence()) { ctx.Emit(R"rs( - fn $hazzer_thunk$(raw_msg: $pbi$::RawMessage) -> bool; - fn $clearer_thunk$(raw_msg: $pbi$::RawMessage); + fn $hazzer_thunk$(raw_msg: $pbr$::RawMessage) -> bool; + fn $clearer_thunk$(raw_msg: $pbr$::RawMessage); )rs"); } }}}, R"rs( $with_presence_fields_thunks$ - fn $getter_thunk$(raw_msg: $pbi$::RawMessage) -> $pbi$::PtrAndLen; - fn $setter_thunk$(raw_msg: $pbi$::RawMessage, val: $pbi$::PtrAndLen); + fn $getter_thunk$(raw_msg: $pbr$::RawMessage) -> $pbr$::PtrAndLen; + fn $setter_thunk$(raw_msg: $pbr$::RawMessage, val: $pbr$::PtrAndLen); )rs"); } diff --git a/src/google/protobuf/compiler/rust/enum.cc b/src/google/protobuf/compiler/rust/enum.cc index ae216fea6f..4184ed0975 100644 --- a/src/google/protobuf/compiler/rust/enum.cc +++ b/src/google/protobuf/compiler/rust/enum.cc @@ -73,14 +73,14 @@ void EnumProxiedInMapValue(Context& ctx, const EnumDescriptor& desc) { .WithSuffix("")}, R"rs( extern "C" { - fn $map_new_thunk$() -> $pbi$::RawMap; - fn $map_free_thunk$(m: $pbi$::RawMap); - fn $map_clear_thunk$(m: $pbi$::RawMap); - fn $map_size_thunk$(m: $pbi$::RawMap) -> usize; - fn $map_insert_thunk$(m: $pbi$::RawMap, key: $ffi_key_t$, value: $name$) -> bool; - fn $map_get_thunk$(m: $pbi$::RawMap, key: $ffi_key_t$, value: *mut $name$) -> bool; - fn $map_remove_thunk$(m: $pbi$::RawMap, key: $ffi_key_t$, value: *mut $name$) -> bool; - fn $map_iter_thunk$(m: $pbi$::RawMap) -> $pbr$::UntypedMapIterator; + fn $map_new_thunk$() -> $pbr$::RawMap; + fn $map_free_thunk$(m: $pbr$::RawMap); + fn $map_clear_thunk$(m: $pbr$::RawMap); + fn $map_size_thunk$(m: $pbr$::RawMap) -> usize; + fn $map_insert_thunk$(m: $pbr$::RawMap, key: $ffi_key_t$, value: $name$) -> bool; + fn $map_get_thunk$(m: $pbr$::RawMap, key: $ffi_key_t$, value: *mut $name$) -> bool; + fn $map_remove_thunk$(m: $pbr$::RawMap, key: $ffi_key_t$, value: *mut $name$) -> bool; + fn $map_iter_thunk$(m: $pbr$::RawMap) -> $pbr$::UntypedMapIterator; fn $map_iter_get_thunk$(iter: &mut $pbr$::UntypedMapIterator, key: *mut $ffi_key_t$, value: *mut $name$); } impl $pb$::ProxiedInMapValue<$key_t$> for $name$ { @@ -170,7 +170,7 @@ void EnumProxiedInMapValue(Context& ctx, const EnumDescriptor& desc) { $pbr$::upb_Map_New( arena.raw(), <$key_t$ as $pbr$::UpbTypeConversions>::upb_type(), - $pbr$::UpbCType::Enum) + $pbr$::CType::Enum) }; $pb$::Map::from_inner( $pbi$::Private, diff --git a/src/google/protobuf/compiler/rust/message.cc b/src/google/protobuf/compiler/rust/message.cc index cf68ff5f56..6ee718fc18 100644 --- a/src/google/protobuf/compiler/rust/message.cc +++ b/src/google/protobuf/compiler/rust/message.cc @@ -202,17 +202,17 @@ void MessageExterns(Context& ctx, const Descriptor& msg) { ThunkName(ctx, msg, "repeated_copy_from")}, }, R"rs( - fn $new_thunk$() -> $pbi$::RawMessage; - fn $delete_thunk$(raw_msg: $pbi$::RawMessage); - fn $serialize_thunk$(raw_msg: $pbi$::RawMessage) -> $pbr$::SerializedData; - fn $parse_thunk$(raw_msg: $pbi$::RawMessage, data: $pbr$::SerializedData) -> bool; - fn $copy_from_thunk$(dst: $pbi$::RawMessage, src: $pbi$::RawMessage); - fn $repeated_len_thunk$(raw: $pbi$::RawRepeatedField) -> usize; - fn $repeated_add_thunk$(raw: $pbi$::RawRepeatedField) -> $pbi$::RawMessage; - fn $repeated_get_thunk$(raw: $pbi$::RawRepeatedField, index: usize) -> $pbi$::RawMessage; - fn $repeated_get_mut_thunk$(raw: $pbi$::RawRepeatedField, index: usize) -> $pbi$::RawMessage; - fn $repeated_clear_thunk$(raw: $pbi$::RawRepeatedField); - fn $repeated_copy_from_thunk$(dst: $pbi$::RawRepeatedField, src: $pbi$::RawRepeatedField); + fn $new_thunk$() -> $pbr$::RawMessage; + fn $delete_thunk$(raw_msg: $pbr$::RawMessage); + fn $serialize_thunk$(raw_msg: $pbr$::RawMessage) -> $pbr$::SerializedData; + fn $parse_thunk$(raw_msg: $pbr$::RawMessage, data: $pbr$::SerializedData) -> bool; + fn $copy_from_thunk$(dst: $pbr$::RawMessage, src: $pbr$::RawMessage); + fn $repeated_len_thunk$(raw: $pbr$::RawRepeatedField) -> usize; + fn $repeated_add_thunk$(raw: $pbr$::RawRepeatedField) -> $pbr$::RawMessage; + fn $repeated_get_thunk$(raw: $pbr$::RawRepeatedField, index: usize) -> $pbr$::RawMessage; + fn $repeated_get_mut_thunk$(raw: $pbr$::RawRepeatedField, index: usize) -> $pbr$::RawMessage; + fn $repeated_clear_thunk$(raw: $pbr$::RawRepeatedField); + fn $repeated_copy_from_thunk$(dst: $pbr$::RawRepeatedField, src: $pbr$::RawRepeatedField); )rs"); return; @@ -223,10 +223,10 @@ void MessageExterns(Context& ctx, const Descriptor& msg) { {"minitable", UpbMinitableName(msg)}, }, R"rs( - fn $new_thunk$(arena: $pbi$::RawArena) -> $pbi$::RawMessage; + fn $new_thunk$(arena: $pbr$::RawArena) -> $pbr$::RawMessage; /// Opaque wrapper for this message's MiniTable. The only valid way to /// reference this static is with `std::ptr::addr_of!(..)`. - static $minitable$: $pbr$::OpaqueMiniTable; + static $minitable$: $pbr$::upb_MiniTable; )rs"); return; } @@ -487,15 +487,15 @@ void MessageProxiedInMapValue(Context& ctx, const Descriptor& msg) { .WithSuffix("")}, R"rs( extern "C" { - fn $map_new_thunk$() -> $pbi$::RawMap; - fn $map_free_thunk$(m: $pbi$::RawMap); - fn $map_clear_thunk$(m: $pbi$::RawMap); - fn $map_size_thunk$(m: $pbi$::RawMap) -> usize; - fn $map_insert_thunk$(m: $pbi$::RawMap, key: $ffi_key_t$, value: $pbi$::RawMessage) -> bool; - fn $map_get_thunk$(m: $pbi$::RawMap, key: $ffi_key_t$, value: *mut $pbi$::RawMessage) -> bool; - fn $map_remove_thunk$(m: $pbi$::RawMap, key: $ffi_key_t$, value: *mut $pbi$::RawMessage) -> bool; - fn $map_iter_thunk$(m: $pbi$::RawMap) -> $pbr$::UntypedMapIterator; - fn $map_iter_get_thunk$(iter: &mut $pbr$::UntypedMapIterator, key: *mut $ffi_key_t$, value: *mut $pbi$::RawMessage); + fn $map_new_thunk$() -> $pbr$::RawMap; + fn $map_free_thunk$(m: $pbr$::RawMap); + fn $map_clear_thunk$(m: $pbr$::RawMap); + fn $map_size_thunk$(m: $pbr$::RawMap) -> usize; + fn $map_insert_thunk$(m: $pbr$::RawMap, key: $ffi_key_t$, value: $pbr$::RawMessage) -> bool; + fn $map_get_thunk$(m: $pbr$::RawMap, key: $ffi_key_t$, value: *mut $pbr$::RawMessage) -> bool; + fn $map_remove_thunk$(m: $pbr$::RawMap, key: $ffi_key_t$, value: *mut $pbr$::RawMessage) -> bool; + fn $map_iter_thunk$(m: $pbr$::RawMap) -> $pbr$::UntypedMapIterator; + fn $map_iter_get_thunk$(iter: &mut $pbr$::UntypedMapIterator, key: *mut $ffi_key_t$, value: *mut $pbr$::RawMessage); } impl $pb$::ProxiedInMapValue<$key_t$> for $Msg$ { fn map_new(_private: $pbi$::Private) -> $pb$::Map<$key_t$, Self> { @@ -580,8 +580,8 @@ void MessageProxiedInMapValue(Context& ctx, const Descriptor& msg) { }, R"rs( impl $pbr$::UpbTypeConversions for $Msg$ { - fn upb_type() -> $pbr$::UpbCType { - $pbr$::UpbCType::Message + fn upb_type() -> $pbr$::CType { + $pbr$::CType::Message } fn to_message_value( @@ -590,7 +590,7 @@ void MessageProxiedInMapValue(Context& ctx, const Descriptor& msg) { } unsafe fn to_message_value_copy_if_required( - arena: $pbi$::RawArena, + arena: $pbr$::RawArena, val: $pb$::View<'_, Self>) -> $pbr$::upb_MessageValue { // Self::to_message_value(val) // SAFETY: The arena memory is not freed due to `ManuallyDrop`. @@ -871,7 +871,7 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { #[derive(Copy, Clone)] #[allow(dead_code)] pub struct $Msg$View<'msg> { - msg: $pbi$::RawMessage, + msg: $pbr$::RawMessage, _phantom: $Phantom$<&'msg ()>, } @@ -884,11 +884,11 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { #[allow(dead_code)] impl<'msg> $Msg$View<'msg> { #[doc(hidden)] - pub fn new(_private: $pbi$::Private, msg: $pbi$::RawMessage) -> Self { + pub fn new(_private: $pbi$::Private, msg: $pbr$::RawMessage) -> Self { Self { msg, _phantom: $std$::marker::PhantomData } } - fn raw_msg(&self) -> $pbi$::RawMessage { + fn raw_msg(&self) -> $pbr$::RawMessage { self.msg } @@ -1010,7 +1010,7 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { pub fn from_parent( _private: $pbi$::Private, parent: $pbr$::MutatorMessageRef<'msg>, - msg: $pbi$::RawMessage) + msg: $pbr$::RawMessage) -> Self { Self { inner: $pbr$::MutatorMessageRef::from_parent( @@ -1026,7 +1026,7 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { #[deprecated = "This .or_default() is a no-op, usages can be safely removed"] pub fn or_default(self) -> Self { self } - fn raw_msg(&self) -> $pbi$::RawMessage { + fn raw_msg(&self) -> $pbr$::RawMessage { self.inner.msg() } @@ -1072,7 +1072,7 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { $Msg::new$ } - fn raw_msg(&self) -> $pbi$::RawMessage { + fn raw_msg(&self) -> $pbr$::RawMessage { self.inner.msg } @@ -1131,10 +1131,10 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { ctx.printer().PrintRaw("\n"); ctx.Emit({{"Msg", RsSafeName(msg.name())}}, R"rs( impl $Msg$ { - pub fn __unstable_wrap_cpp_grant_permission_to_break(msg: $pbi$::RawMessage) -> Self { + pub fn __unstable_wrap_cpp_grant_permission_to_break(msg: $pbr$::RawMessage) -> Self { Self { inner: $pbr$::MessageInner { msg } } } - pub fn __unstable_leak_cpp_repr_grant_permission_to_break(self) -> $pbi$::RawMessage { + pub fn __unstable_leak_cpp_repr_grant_permission_to_break(self) -> $pbr$::RawMessage { let s = std::mem::ManuallyDrop::new(self); s.raw_msg() } @@ -1144,12 +1144,12 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { //~ msg is a &mut so that the borrow checker enforces exclusivity to //~ prevent constructing multiple Muts/Views from the same RawMessage. pub fn __unstable_wrap_cpp_grant_permission_to_break( - msg: &'a mut $pbi$::RawMessage) -> Self { + msg: &'a mut $pbr$::RawMessage) -> Self { Self { inner: $pbr$::MutatorMessageRef::from_raw_msg($pbi$::Private, msg) } } - pub fn __unstable_cpp_repr_grant_permission_to_break(self) -> $pbi$::RawMessage { + pub fn __unstable_cpp_repr_grant_permission_to_break(self) -> $pbr$::RawMessage { self.raw_msg() } } @@ -1158,10 +1158,10 @@ void GenerateRs(Context& ctx, const Descriptor& msg) { //~ msg is a & so that the caller can claim the message is live for the //~ corresponding lifetime. pub fn __unstable_wrap_cpp_grant_permission_to_break( - msg: &'a $pbi$::RawMessage) -> Self { + msg: &'a $pbr$::RawMessage) -> Self { Self::new($pbi$::Private, *msg) } - pub fn __unstable_cpp_repr_grant_permission_to_break(self) -> $pbi$::RawMessage { + pub fn __unstable_cpp_repr_grant_permission_to_break(self) -> $pbr$::RawMessage { self.msg } } diff --git a/src/google/protobuf/compiler/rust/naming.cc b/src/google/protobuf/compiler/rust/naming.cc index 745f6a6afd..6879e4ae45 100644 --- a/src/google/protobuf/compiler/rust/naming.cc +++ b/src/google/protobuf/compiler/rust/naming.cc @@ -421,7 +421,7 @@ PROTOBUF_CONSTINIT const MapKeyType kMapKeyTypes[] = { /*cc_to_ffi_key_expr=*/"cpp_key"}, {/*thunk_ident=*/"ProtoStr", /*rs_key_t=*/"$pb$::ProtoStr", - /*rs_ffi_key_t=*/"$pbi$::PtrAndLen", + /*rs_ffi_key_t=*/"$pbr$::PtrAndLen", /*rs_to_ffi_key_expr=*/"key.as_bytes().into()", /*rs_from_ffi_key_expr=*/ "$pb$::ProtoStr::from_utf8_unchecked(ffi_key.as_ref())", diff --git a/src/google/protobuf/compiler/rust/oneof.cc b/src/google/protobuf/compiler/rust/oneof.cc index f2c82a876c..8453af898b 100644 --- a/src/google/protobuf/compiler/rust/oneof.cc +++ b/src/google/protobuf/compiler/rust/oneof.cc @@ -231,7 +231,7 @@ void GenerateOneofExternC(Context& ctx, const OneofDescriptor& oneof) { {"case_thunk", ThunkName(ctx, oneof, "case")}, }, R"rs( - fn $case_thunk$(raw_msg: $pbi$::RawMessage) -> $oneof_enum_module$$case_enum_rs_name$; + fn $case_thunk$(raw_msg: $pbr$::RawMessage) -> $oneof_enum_module$$case_enum_rs_name$; )rs"); }