Skip to content

Commit 5a48187

Browse files
Move internal-only but kernel-agnostic paths into an __internal module
Add some documentation along the way. PiperOrigin-RevId: 540311409
1 parent e4b500c commit 5a48187

File tree

8 files changed

+113
-55
lines changed

8 files changed

+113
-55
lines changed

rust/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ rust_library(
4949
rust_library(
5050
name = "protobuf_upb",
5151
srcs = [
52+
"internal.rs",
5253
"proxied.rs",
5354
"shared.rs",
5455
"upb.rs",
@@ -83,6 +84,7 @@ rust_library(
8384
name = "protobuf_cpp",
8485
srcs = [
8586
"cpp.rs",
87+
"internal.rs",
8688
"proxied.rs",
8789
"shared.rs",
8890
],

rust/internal.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Protocol Buffers - Google's data interchange format
2+
// Copyright 2023 Google Inc. All rights reserved.
3+
// https://developers.google.com/protocol-buffers/
4+
//
5+
// Redistribution and use in source and binary forms, with or without
6+
// modification, are permitted provided that the following conditions are
7+
// met:
8+
//
9+
// * Redistributions of source code must retain the above copyright
10+
// notice, this list of conditions and the following disclaimer.
11+
// * Redistributions in binary form must reproduce the above
12+
// copyright notice, this list of conditions and the following disclaimer
13+
// in the documentation and/or other materials provided with the
14+
// distribution.
15+
// * Neither the name of Google Inc. nor the names of its
16+
// contributors may be used to endorse or promote products derived from
17+
// this software without specific prior written permission.
18+
//
19+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
31+
//! Kernel-agnostic logic for the Rust Protobuf runtime that should not be
32+
//! exposed to through the `protobuf` path but must be public for use by
33+
//! generated code.
34+
35+
use std::slice;
36+
37+
/// Represents an ABI-stable version of `NonNull<[u8]>`/`string_view` (a
38+
/// borrowed slice of bytes) for FFI use only.
39+
///
40+
/// Has semantics similar to `std::string_view` in C++ and `&[u8]` in Rust,
41+
/// but is not ABI-compatible with either.
42+
///
43+
/// If `len` is 0, then `ptr` can be null or dangling. C++ considers a dangling
44+
/// 0-len `std::string_view` to be invalid, and Rust considers a `&[u8]` with a
45+
/// null data pointer to be invalid.
46+
#[repr(C)]
47+
#[derive(Copy, Clone)]
48+
pub struct PtrAndLen {
49+
/// Pointer to the first byte.
50+
/// Borrows the memory.
51+
pub ptr: *const u8,
52+
53+
/// Length of the `[u8]` pointed to by `ptr`.
54+
pub len: usize,
55+
}
56+
57+
impl PtrAndLen {
58+
/// Unsafely dereference this slice.
59+
///
60+
/// # Safety
61+
/// - `ptr` must be valid for `len` bytes. It can be null or dangling if
62+
/// `self.len == 0`.
63+
pub unsafe fn as_ref<'a>(self) -> &'a [u8] {
64+
if self.ptr.is_null() {
65+
assert_eq!(self.len, 0, "Non-empty slice with null data pointer");
66+
&[]
67+
} else {
68+
slice::from_raw_parts(self.ptr, self.len)
69+
}
70+
}
71+
}

rust/protobuf.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@
3030

3131
//! Rust Protobuf Runtime
3232
//!
33-
//! This file forwards to the kernel specific implementation. Rust Protobuf
34-
//! gencode actually depends directly on kernel specific crates. The only reason
35-
//! this crate exists is to be able to use `protobuf` as a crate name for both
36-
//! cpp and upb kernels from user code.
33+
//! This file forwards to `shared.rs`, which exports a kernel-specific
34+
//! `__runtime`. Rust Protobuf gencode actually depends directly on kernel
35+
//! specific crates. The only reason this crate exists is to be able to use
36+
//! `protobuf` as a crate name for both cpp and upb kernels from user code.
3737
3838
#[cfg(cpp_kernel)]
39-
pub use protobuf_cpp::*;
39+
use protobuf_cpp as kernel;
40+
4041
#[cfg(upb_kernel)]
41-
pub use protobuf_upb::*;
42+
use protobuf_upb as kernel;
43+
44+
pub use kernel::{Mut, MutProxy, ParseError, Proxied, View, ViewProxy};

rust/shared.rs

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@
3030

3131
//! Kernel-agnostic logic for the Rust Protobuf Runtime.
3232
//!
33-
//! For kernel-specific logic this crate delegates to the respective __runtime
33+
//! For kernel-specific logic this crate delegates to the respective `__runtime`
3434
//! crate.
3535
36+
/// Everything in `__runtime` is allowed to change without it being considered
37+
/// a breaking change for the protobuf library. Nothing in here should be
38+
/// exported in `protobuf.rs`.
3639
#[cfg(cpp_kernel)]
3740
#[path = "cpp.rs"]
3841
pub mod __runtime;
@@ -42,11 +45,15 @@ pub mod __runtime;
4245

4346
mod proxied;
4447

45-
pub use __runtime::SerializedData;
48+
pub use proxied::{Mut, MutProxy, Proxied, View, ViewProxy};
49+
50+
/// Everything in `__internal` is allowed to change without it being considered
51+
/// a breaking change for the protobuf library. Nothing in here should be
52+
/// exported in `protobuf.rs`.
53+
#[path = "internal.rs"]
54+
pub mod __internal;
4655

4756
use std::fmt;
48-
use std::slice;
49-
use std::ptr::NonNull;
5057

5158
/// An error that happened during deserialization.
5259
#[derive(Debug, Clone)]
@@ -57,28 +64,3 @@ impl fmt::Display for ParseError {
5764
write!(f, "Couldn't deserialize given bytes into a proto")
5865
}
5966
}
60-
61-
/// An ABI-stable, FFI-safe borrowed slice of bytes.
62-
///
63-
/// Has semantics equivalent to `&[u8]` in Rust and `std::string_view` in C++,
64-
/// but is not ABI-compatible with them.
65-
///
66-
/// TODO: Is `ptr` allowed to be null or dangling when `len` is 0?
67-
#[repr(C)]
68-
#[derive(Copy, Clone)]
69-
pub struct PtrAndLen {
70-
/// Borrows the memory.
71-
pub ptr: *const u8,
72-
pub len: usize,
73-
}
74-
75-
impl PtrAndLen {
76-
pub unsafe fn as_ref<'a>(self) -> &'a [u8] {
77-
assert!(self.len == 0 || !self.ptr.is_null());
78-
if self.len == 0 {
79-
slice::from_raw_parts(NonNull::dangling().as_ptr(), 0)
80-
} else {
81-
slice::from_raw_parts(self.ptr, self.len)
82-
}
83-
}
84-
}

rust/test/cpp/interop/main.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ macro_rules! proto_assert_eq {
4848
extern "C" {
4949
fn DeserializeTestAllTypes(data: *const u8, len: usize) -> NonNull<u8>;
5050
fn MutateTestAllTypes(msg: NonNull<u8>);
51-
fn SerializeTestAllTypes(msg: NonNull<u8>) -> protobuf_cpp::SerializedData;
51+
fn SerializeTestAllTypes(msg: NonNull<u8>) -> protobuf_cpp::__runtime::SerializedData;
5252

5353
fn NewWithExtension() -> NonNull<u8>;
54-
fn GetBytesExtension(msg: NonNull<u8>) -> protobuf_cpp::PtrAndLen;
54+
fn GetBytesExtension(msg: NonNull<u8>) -> protobuf_cpp::__internal::PtrAndLen;
5555
}
5656

5757
#[test]
@@ -91,7 +91,7 @@ fn deserialize_in_cpp() {
9191

9292
let msg2 = unsafe {
9393
TestAllTypes::__unstable_wrap_cpp_grant_permission_to_break(DeserializeTestAllTypes(
94-
data.as_ptr(),
94+
(*data).as_ptr(),
9595
data.len(),
9696
))
9797
};
@@ -110,8 +110,7 @@ fn smuggle_extension() {
110110

111111
let mut msg2 = TestAllExtensions::new();
112112
msg2.deserialize(&data).unwrap();
113-
let bytes = unsafe {
114-
GetBytesExtension(msg2.__unstable_cpp_repr_grant_permission_to_break()).as_ref()
115-
};
113+
let bytes =
114+
unsafe { GetBytesExtension(msg2.__unstable_cpp_repr_grant_permission_to_break()).as_ref() };
116115
assert_eq!(&*bytes, b"smuggled");
117116
}

src/google/protobuf/compiler/rust/accessors/singular_bytes.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class SingularBytes final : public AccessorGenerator {
8484
},
8585
R"rs(
8686
fn $hazzer_thunk$(raw_msg: $NonNull$<u8>) -> bool;
87-
fn $getter_thunk$(raw_msg: $NonNull$<u8>) -> $pb$::PtrAndLen;
87+
fn $getter_thunk$(raw_msg: $NonNull$<u8>) -> $pbi$::PtrAndLen;
8888
fn $setter_thunk$(raw_msg: $NonNull$<u8>, val: *const u8, len: usize);
8989
fn $clearer_thunk$(raw_msg: $NonNull$<u8>);
9090
)rs");

src/google/protobuf/compiler/rust/generator.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ bool RustGenerator::Generate(const FileDescriptor* file_desc,
9797
auto v = file.printer().WithVars({
9898
{"std", "::__std"},
9999
{"pb", "::__pb"},
100-
{"pbi", "::__pb::__runtime"},
100+
{"pbi", "::__pb::__internal"},
101+
{"pbr", "::__pb::__runtime"},
101102
{"NonNull", "::__std::ptr::NonNull"},
102103
});
103104

src/google/protobuf/compiler/rust/message.cc

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void MessageStructFields(Context<Descriptor> msg) {
5959
//~ rustc incorrectly thinks this field is never read, even though
6060
//~ it has a destructor!
6161
#[allow(dead_code)]
62-
arena: $pbi$::Arena,
62+
arena: $pbr$::Arena,
6363
)rs");
6464
return;
6565
}
@@ -77,7 +77,7 @@ void MessageNew(Context<Descriptor> msg) {
7777

7878
case Kernel::kUpb:
7979
msg.Emit({{"new_thunk", Thunk(msg, "new")}}, R"rs(
80-
let arena = $pbi$::Arena::new();
80+
let arena = $pbr$::Arena::new();
8181
Self {
8282
msg: unsafe { $new_thunk$(arena.raw()) },
8383
arena,
@@ -99,11 +99,11 @@ void MessageSerialize(Context<Descriptor> msg) {
9999

100100
case Kernel::kUpb:
101101
msg.Emit({{"serialize_thunk", Thunk(msg, "serialize")}}, R"rs(
102-
let arena = $pbi$::Arena::new();
102+
let arena = $pbr$::Arena::new();
103103
let mut len = 0;
104104
unsafe {
105105
let data = $serialize_thunk$(self.msg, arena.raw(), &mut len);
106-
$pb$::SerializedData::from_raw_parts(arena, data, len)
106+
$pbr$::SerializedData::from_raw_parts(arena, data, len)
107107
}
108108
)rs");
109109
return;
@@ -121,7 +121,7 @@ void MessageDeserialize(Context<Descriptor> msg) {
121121
},
122122
R"rs(
123123
let success = unsafe {
124-
let data = $pb$::SerializedData::from_raw_parts(
124+
let data = $pbr$::SerializedData::from_raw_parts(
125125
$NonNull$::new(data.as_ptr() as *mut _).unwrap(),
126126
data.len(),
127127
);
@@ -134,7 +134,7 @@ void MessageDeserialize(Context<Descriptor> msg) {
134134

135135
case Kernel::kUpb:
136136
msg.Emit({{"deserialize_thunk", Thunk(msg, "parse")}}, R"rs(
137-
let arena = $pbi$::Arena::new();
137+
let arena = $pbr$::Arena::new();
138138
let msg = unsafe {
139139
$NonNull$::<u8>::new(
140140
$deserialize_thunk$(data.as_ptr(), data.len(), arena.raw())
@@ -171,8 +171,8 @@ void MessageExterns(Context<Descriptor> msg) {
171171
R"rs(
172172
fn $new_thunk$() -> $NonNull$<u8>;
173173
fn $delete_thunk$(raw_msg: $NonNull$<u8>);
174-
fn $serialize_thunk$(raw_msg: $NonNull$<u8>) -> $pb$::SerializedData;
175-
fn $deserialize_thunk$(raw_msg: $NonNull$<u8>, data: $pb$::SerializedData) -> bool;
174+
fn $serialize_thunk$(raw_msg: $NonNull$<u8>) -> $pbr$::SerializedData;
175+
fn $deserialize_thunk$(raw_msg: $NonNull$<u8>, data: $pbr$::SerializedData) -> bool;
176176
)rs");
177177
return;
178178

@@ -184,9 +184,9 @@ void MessageExterns(Context<Descriptor> msg) {
184184
{"deserialize_thunk", Thunk(msg, "parse")},
185185
},
186186
R"rs(
187-
fn $new_thunk$(arena: $pbi$::RawArena) -> $NonNull$<u8>;
188-
fn $serialize_thunk$(msg: $NonNull$<u8>, arena: $pbi$::RawArena, len: &mut usize) -> $NonNull$<u8>;
189-
fn $deserialize_thunk$(data: *const u8, size: usize, arena: $pbi$::RawArena) -> *mut u8;
187+
fn $new_thunk$(arena: $pbr$::RawArena) -> $NonNull$<u8>;
188+
fn $serialize_thunk$(msg: $NonNull$<u8>, arena: $pbr$::RawArena, len: &mut usize) -> $NonNull$<u8>;
189+
fn $deserialize_thunk$(data: *const u8, size: usize, arena: $pbr$::RawArena) -> *mut u8;
190190
)rs");
191191
return;
192192
}
@@ -293,7 +293,7 @@ void MessageGenerator::GenerateRs(Context<Descriptor> msg) {
293293
$Msg::new$
294294
}
295295
296-
pub fn serialize(&self) -> $pb$::SerializedData {
296+
pub fn serialize(&self) -> $pbr$::SerializedData {
297297
$Msg::serialize$
298298
}
299299
pub fn deserialize(&mut self, data: &[u8]) -> Result<(), $pb$::ParseError> {

0 commit comments

Comments
 (0)