blob: be9ddb220362533f76ca709e348a8cd8128e1d13 [file] [log] [blame]
Protobuf Team Bot5a481872023-06-14 10:29:31 -07001// Protocol Buffers - Google's data interchange format
Hong Shin4f20efb2023-07-10 07:35:36 -07002// Copyright 2023 Google LLC. All rights reserved.
Protobuf Team Bot5a481872023-06-14 10:29:31 -07003//
Joshua Haberman4a513032023-09-08 17:12:50 -07004// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file or at
6// https://developers.google.com/open-source/licenses/bsd
Protobuf Team Bot5a481872023-06-14 10:29:31 -07007
8//! Kernel-agnostic logic for the Rust Protobuf runtime that should not be
9//! exposed to through the `protobuf` path but must be public for use by
10//! generated code.
11
Alyssa Haroldsen9a0bc392023-08-23 11:05:31 -070012pub use crate::vtable::{
Adrian Sadłochac3031092023-10-18 08:34:52 -070013 new_vtable_field_entry, BytesMutVTable, BytesOptionalMutVTable, PrimitiveOptionalMutVTable,
14 PrimitiveVTable, RawVTableMutator,
Alyssa Haroldsen9a0bc392023-08-23 11:05:31 -070015};
Hong Shin5c33ed02023-08-24 16:34:08 -070016use std::ptr::NonNull;
Protobuf Team Bot5a481872023-06-14 10:29:31 -070017use std::slice;
18
Protobuf Team Bot29a26152023-06-22 09:51:38 -070019/// Used to protect internal-only items from being used accidentally.
20pub struct Private;
21
Hong Shin5c33ed02023-08-24 16:34:08 -070022/// Defines a set of opaque, unique, non-accessible pointees.
23///
24/// The [Rustonomicon][nomicon] currently recommends a zero-sized struct,
25/// though this should use [`extern type`] when that is stabilized.
26/// [nomicon]: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs
27/// [`extern type`]: https://github.com/rust-lang/rust/issues/43467
28mod _opaque_pointees {
29 /// Opaque pointee for [`RawMessage`]
30 ///
31 /// This type is not meant to be dereferenced in Rust code.
32 /// It is only meant to provide type safety for raw pointers
33 /// which are manipulated behind FFI.
34 ///
35 /// [`RawMessage`]: super::RawMessage
36 #[repr(C)]
37 pub struct RawMessageData {
38 _data: [u8; 0],
39 _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>,
40 }
Protobuf Team Bot15253002023-08-01 16:20:23 -070041
Hong Shin5c33ed02023-08-24 16:34:08 -070042 /// Opaque pointee for [`RawArena`]
43 ///
44 /// This type is not meant to be dereferenced in Rust code.
45 /// It is only meant to provide type safety for raw pointers
46 /// which are manipulated behind FFI.
47 ///
48 /// [`RawArena`]: super::RawArena
49 #[repr(C)]
50 pub struct RawArenaData {
51 _data: [u8; 0],
52 _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>,
53 }
Protobuf Team Bote1bb7d62023-10-17 14:15:37 -070054
55 /// Opaque pointee for [`RawRepeatedField`]
56 ///
57 /// This type is not meant to be dereferenced in Rust code.
58 /// It is only meant to provide type safety for raw pointers
59 /// which are manipulated behind FFI.
60 #[repr(C)]
61 pub struct RawRepeatedFieldData {
62 _data: [u8; 0],
63 _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>,
64 }
Jakob Buchgraberac3f5532023-11-08 02:13:42 -080065
66 /// Opaque pointee for [`RawMap`]
67 ///
68 /// This type is not meant to be dereferenced in Rust code.
69 /// It is only meant to provide type safety for raw pointers
70 /// which are manipulated behind FFI.
71 #[repr(C)]
72 pub struct RawMapData {
73 _data: [u8; 0],
74 _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>,
75 }
Hong Shin5c33ed02023-08-24 16:34:08 -070076}
77
78/// A raw pointer to the underlying message for this runtime.
79pub type RawMessage = NonNull<_opaque_pointees::RawMessageData>;
80
81/// A raw pointer to the underlying arena for this runtime.
82pub type RawArena = NonNull<_opaque_pointees::RawArenaData>;
Protobuf Team Bot15253002023-08-01 16:20:23 -070083
Protobuf Team Bote1bb7d62023-10-17 14:15:37 -070084/// A raw pointer to the underlying repeated field container for this runtime.
85pub type RawRepeatedField = NonNull<_opaque_pointees::RawRepeatedFieldData>;
86
Jakob Buchgraberac3f5532023-11-08 02:13:42 -080087/// A raw pointer to the underlying arena for this runtime.
88pub type RawMap = NonNull<_opaque_pointees::RawMapData>;
89
Protobuf Team Bot5a481872023-06-14 10:29:31 -070090/// Represents an ABI-stable version of `NonNull<[u8]>`/`string_view` (a
91/// borrowed slice of bytes) for FFI use only.
92///
93/// Has semantics similar to `std::string_view` in C++ and `&[u8]` in Rust,
94/// but is not ABI-compatible with either.
95///
96/// If `len` is 0, then `ptr` can be null or dangling. C++ considers a dangling
97/// 0-len `std::string_view` to be invalid, and Rust considers a `&[u8]` with a
98/// null data pointer to be invalid.
99#[repr(C)]
100#[derive(Copy, Clone)]
101pub struct PtrAndLen {
102 /// Pointer to the first byte.
103 /// Borrows the memory.
104 pub ptr: *const u8,
105
106 /// Length of the `[u8]` pointed to by `ptr`.
107 pub len: usize,
108}
109
110impl PtrAndLen {
111 /// Unsafely dereference this slice.
112 ///
113 /// # Safety
Protobuf Team Bot49d3bca2023-07-18 11:46:53 -0700114 /// - `self.ptr` must be dereferencable and immutable for `self.len` bytes
115 /// for the lifetime `'a`. It can be null or dangling if `self.len == 0`.
Protobuf Team Bot5a481872023-06-14 10:29:31 -0700116 pub unsafe fn as_ref<'a>(self) -> &'a [u8] {
117 if self.ptr.is_null() {
118 assert_eq!(self.len, 0, "Non-empty slice with null data pointer");
119 &[]
120 } else {
Protobuf Team Bot49d3bca2023-07-18 11:46:53 -0700121 // SAFETY:
122 // - `ptr` is non-null
123 // - `ptr` is valid for `len` bytes as promised by the caller.
124 unsafe { slice::from_raw_parts(self.ptr, self.len) }
Protobuf Team Bot5a481872023-06-14 10:29:31 -0700125 }
126 }
127}
Protobuf Team Bot78d71ca2023-09-13 11:55:59 -0700128
129impl From<&[u8]> for PtrAndLen {
130 fn from(slice: &[u8]) -> Self {
131 Self { ptr: slice.as_ptr(), len: slice.len() }
132 }
133}