Add an protobuf::__internal::SealedInternal trait
The purpose of this trait is that it is declared as a supertrait of the traits that we don't want application code to implement (like "Proxied" and "MessageView"); application code can see those traits but not the supertrait, which enables them to use them but not implement them.
PiperOrigin-RevId: 657555025
diff --git a/rust/codegen_traits.rs b/rust/codegen_traits.rs
index ad8dd64..3cd94df 100644
--- a/rust/codegen_traits.rs
+++ b/rust/codegen_traits.rs
@@ -7,6 +7,7 @@
//! Traits that are implemeted by codegen types.
+use crate::__internal::SealedInternal;
use crate::{MutProxied, MutProxy, ViewProxy};
use create::Parse;
use read::Serialize;
@@ -14,7 +15,8 @@
use write::{Clear, ClearAndParse};
/// A trait that all generated owned message types implement.
-pub trait Message: MutProxied
+pub trait Message: SealedInternal
+ + MutProxied
// Create traits:
+ Parse + Default
// Read traits:
@@ -28,7 +30,8 @@
{}
/// A trait that all generated message views implement.
-pub trait MessageView<'msg>: ViewProxy<'msg, Proxied = Self::Message>
+pub trait MessageView<'msg>: SealedInternal
+ + ViewProxy<'msg, Proxied = Self::Message>
// Read traits:
+ Debug + Serialize
// Thread safety:
@@ -41,8 +44,8 @@
}
/// A trait that all generated message muts implement.
-pub trait MessageMut<'msg>:
- MutProxy<'msg, MutProxied = Self::Message>
+pub trait MessageMut<'msg>: SealedInternal
+ + MutProxy<'msg, MutProxied = Self::Message>
// Read traits:
+ Debug + Serialize
// Write traits:
@@ -60,7 +63,8 @@
/// Operations related to constructing a message. Only owned messages implement
/// these traits.
pub(crate) mod create {
- pub trait Parse: Sized {
+ use super::SealedInternal;
+ pub trait Parse: SealedInternal + Sized {
fn parse(serialized: &[u8]) -> Result<Self, crate::ParseError>;
}
}
@@ -69,7 +73,9 @@
/// have a `&self` receiver on an owned message). Owned messages, views, and
/// muts all implement these traits.
pub(crate) mod read {
- pub trait Serialize {
+ use super::SealedInternal;
+
+ pub trait Serialize: SealedInternal {
fn serialize(&self) -> Result<Vec<u8>, crate::SerializeError>;
}
}
@@ -78,12 +84,13 @@
/// self` receiver on an owned message). Owned messages and muts implement these
/// traits.
pub(crate) mod write {
+ use super::SealedInternal;
- pub trait Clear {
+ pub trait Clear: SealedInternal {
fn clear(&mut self);
}
- pub trait ClearAndParse {
+ pub trait ClearAndParse: SealedInternal {
fn clear_and_parse(&mut self, data: &[u8]) -> Result<(), crate::ParseError>;
}
}
diff --git a/rust/cord.rs b/rust/cord.rs
index 14c9a60..19fdb0b 100644
--- a/rust/cord.rs
+++ b/rust/cord.rs
@@ -5,7 +5,7 @@
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
-use crate::__internal::Private;
+use crate::__internal::{Private, SealedInternal};
use crate::{
AsView, IntoProxied, IntoView, ProtoBytes, ProtoStr, ProtoString, Proxied, Proxy, View,
ViewProxy,
@@ -26,6 +26,10 @@
Owned($t),
}
+ impl SealedInternal for [< $t Cord>] {}
+
+ impl<'msg> SealedInternal for [< $t Cow>]<'msg> {}
+
impl Proxied for [< $t Cord>] {
type View<'msg> = [< $t Cow>]<'msg>;
}
diff --git a/rust/internal.rs b/rust/internal.rs
index c2bdd00..a2397bd 100644
--- a/rust/internal.rs
+++ b/rust/internal.rs
@@ -23,3 +23,11 @@
/// Used to protect internal-only items from being used accidentally.
#[derive(Debug)]
pub struct Private;
+
+/// A trait that is used as a subtrait of traits that we intend to be used but
+/// not be implemented by users.
+///
+/// This is slightly less 'sealed' than the typical sealed trait pattern would
+/// permit in other crates; this trait is intended to be available to crates
+/// which were generated by protoc, but not to application code.
+pub trait SealedInternal {}
diff --git a/rust/map.rs b/rust/map.rs
index 57647d6..ec72d9a 100644
--- a/rust/map.rs
+++ b/rust/map.rs
@@ -8,7 +8,7 @@
use crate::{
AsMut, AsView, IntoMut, IntoProxied, IntoView, Mut, MutProxied, MutProxy, Proxied, Proxy, View,
ViewProxy,
- __internal::Private,
+ __internal::{Private, SealedInternal},
__runtime::{InnerMap, InnerMapMut, RawMap, RawMapIter},
};
use std::marker::PhantomData;
@@ -72,6 +72,8 @@
// it does not use thread-local data or similar.
unsafe impl<K: Proxied, V: ProxiedInMapValue<K>> Send for Map<K, V> {}
+impl<K: Proxied, V: ProxiedInMapValue<K>> SealedInternal for Map<K, V> {}
+
impl<K: Proxied, V: ProxiedInMapValue<K>> Drop for Map<K, V> {
fn drop(&mut self) {
// SAFETY:
@@ -129,6 +131,8 @@
}
}
+impl<'msg, K: Proxied, V: ProxiedInMapValue<K>> SealedInternal for MapView<'msg, K, V> {}
+
impl<'msg, K: Proxied, V: ProxiedInMapValue<K>> Proxy<'msg> for MapView<'msg, K, V> {}
impl<'msg, K: Proxied, V: ProxiedInMapValue<K>> AsView for MapView<'msg, K, V> {
@@ -150,6 +154,8 @@
impl<'msg, K: Proxied, V: ProxiedInMapValue<K>> ViewProxy<'msg> for MapView<'msg, K, V> {}
+impl<'msg, K: Proxied, V: ProxiedInMapValue<K>> SealedInternal for MapMut<'msg, K, V> {}
+
impl<'msg, K: Proxied, V: ProxiedInMapValue<K>> Proxy<'msg> for MapMut<'msg, K, V> {}
impl<'msg, K: Proxied, V: ProxiedInMapValue<K>> AsView for MapMut<'msg, K, V> {
diff --git a/rust/primitive.rs b/rust/primitive.rs
index a87f330..bf5af33 100644
--- a/rust/primitive.rs
+++ b/rust/primitive.rs
@@ -4,11 +4,14 @@
// 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
+use crate::__internal::SealedInternal;
use crate::{AsView, IntoView, Proxied, Proxy, ViewProxy};
macro_rules! impl_singular_primitives {
($($t:ty),*) => {
$(
+ impl SealedInternal for $t {}
+
impl Proxied for $t {
type View<'msg> = $t;
}
diff --git a/rust/proxied.rs b/rust/proxied.rs
index c56b185..3214790 100644
--- a/rust/proxied.rs
+++ b/rust/proxied.rs
@@ -44,7 +44,7 @@
//! implemented the concept of "proxy" types. Proxy types are a reference-like
//! indirection between the user and the internal memory representation.
-use crate::__internal::Private;
+use crate::__internal::{Private, SealedInternal};
use std::fmt::Debug;
/// A type that can be accessed through a reference-like proxy.
@@ -52,7 +52,7 @@
/// An instance of a `Proxied` can be accessed immutably via `Proxied::View`.
///
/// All Protobuf field types implement `Proxied`.
-pub trait Proxied: AsView<Proxied = Self> + Sized {
+pub trait Proxied: SealedInternal + AsView<Proxied = Self> + Sized {
/// The proxy type that provides shared access to a `T`, like a `&'msg T`.
///
/// Most code should use the type alias [`View`].
@@ -67,7 +67,7 @@
/// and immutably via `MutProxied::View`.
///
/// `MutProxied` is implemented by message, map and repeated field types.
-pub trait MutProxied: Proxied + AsMut<MutProxied = Self> {
+pub trait MutProxied: SealedInternal + Proxied + AsMut<MutProxied = Self> {
/// The proxy type that provides exclusive mutable access to a `T`, like a
/// `&'msg mut T`.
///
@@ -95,7 +95,7 @@
/// types.
///
/// On ViewProxy this will behave as a reborrow into a shorter lifetime.
-pub trait AsView {
+pub trait AsView: SealedInternal {
type Proxied: Proxied;
/// Converts a borrow into a `View` with the lifetime of that borrow.
@@ -127,7 +127,7 @@
///
/// On a ViewProxy this will behave as a reborrow into a shorter lifetime
/// (semantically matching a `&'a T` into a `&'b T` where `'a: 'b`).
-pub trait IntoView<'msg>: AsView {
+pub trait IntoView<'msg>: SealedInternal + AsView {
/// Converts into a `View` with a potentially shorter lifetime.
///
/// In non-generic code we don't need to use `into_view` because the proxy
@@ -162,7 +162,7 @@
/// implemented on both owned `Proxied` types as well as MutProxy types.
///
/// On MutProxy this will behave as a reborrow into a shorter lifetime.
-pub trait AsMut: AsView<Proxied = Self::MutProxied> {
+pub trait AsMut: SealedInternal + AsView<Proxied = Self::MutProxied> {
type MutProxied: MutProxied;
/// Converts a borrow into a `Mut` with the lifetime of that borrow.
@@ -173,7 +173,7 @@
///
/// On a MutProxy this will behave as a reborrow into a shorter lifetime
/// (semantically matching a `&mut 'a T` into a `&mut 'b T` where `'a: 'b`).
-pub trait IntoMut<'msg>: AsMut {
+pub trait IntoMut<'msg>: SealedInternal + AsMut {
/// Converts into a `Mut` with a potentially shorter lifetime.
///
/// In non-generic code we don't need to use `into_mut` because the proxy
@@ -206,16 +206,19 @@
///
/// This trait is intentionally made non-object-safe to prevent a potential
/// future incompatible change.
-pub trait Proxy<'msg>: 'msg + IntoView<'msg> + Sync + Unpin + Sized + Debug {}
+pub trait Proxy<'msg>:
+ SealedInternal + 'msg + IntoView<'msg> + Sync + Unpin + Sized + Debug
+{
+}
/// Declares conversion operations common to view proxies.
-pub trait ViewProxy<'msg>: Proxy<'msg> + Send {}
+pub trait ViewProxy<'msg>: SealedInternal + Proxy<'msg> + Send {}
/// Declares operations common to all mut proxies.
///
/// This trait is intentionally made non-object-safe to prevent a potential
/// future incompatible change.
-pub trait MutProxy<'msg>: Proxy<'msg> + AsMut + IntoMut<'msg> {
+pub trait MutProxy<'msg>: SealedInternal + Proxy<'msg> + AsMut + IntoMut<'msg> {
/// Gets an immutable view of this field. This is shorthand for `as_view`.
///
/// This provides a shorter lifetime than `into_view` but can also be called
@@ -265,6 +268,8 @@
}
}
+ impl SealedInternal for MyProxied {}
+
impl Proxied for MyProxied {
type View<'msg> = MyProxiedView<'msg>;
}
@@ -292,6 +297,8 @@
my_proxied_ref: &'msg MyProxied,
}
+ impl<'msg> SealedInternal for MyProxiedView<'msg> {}
+
impl MyProxiedView<'_> {
fn val(&self) -> &str {
&self.my_proxied_ref.val
@@ -324,6 +331,8 @@
my_proxied_ref: &'msg mut MyProxied,
}
+ impl<'msg> SealedInternal for MyProxiedMut<'msg> {}
+
impl<'msg> Proxy<'msg> for MyProxiedMut<'msg> {}
impl<'msg> AsView for MyProxiedMut<'msg> {
diff --git a/rust/repeated.rs b/rust/repeated.rs
index 1a43dce..1fd5e0e 100644
--- a/rust/repeated.rs
+++ b/rust/repeated.rs
@@ -17,7 +17,7 @@
use crate::{
AsMut, AsView, IntoMut, IntoProxied, IntoView, Mut, MutProxied, MutProxy, Proxied, Proxy, View,
ViewProxy,
- __internal::Private,
+ __internal::{Private, SealedInternal},
__runtime::{InnerRepeated, InnerRepeatedMut, RawRepeatedField},
};
@@ -382,6 +382,8 @@
type View<'msg> = RepeatedView<'msg, T> where Repeated<T>: 'msg;
}
+impl<T> SealedInternal for Repeated<T> where T: ProxiedInRepeated {}
+
impl<T> AsView for Repeated<T>
where
T: ProxiedInRepeated,
@@ -411,6 +413,8 @@
}
}
+impl<'msg, T> SealedInternal for RepeatedView<'msg, T> where T: ProxiedInRepeated + 'msg {}
+
impl<'msg, T> Proxy<'msg> for RepeatedView<'msg, T> where T: ProxiedInRepeated + 'msg {}
impl<'msg, T> AsView for RepeatedView<'msg, T>
@@ -440,6 +444,8 @@
impl<'msg, T> ViewProxy<'msg> for RepeatedView<'msg, T> where T: ProxiedInRepeated + 'msg {}
+impl<'msg, T> SealedInternal for RepeatedMut<'msg, T> where T: ProxiedInRepeated + 'msg {}
+
impl<'msg, T> Proxy<'msg> for RepeatedMut<'msg, T> where T: ProxiedInRepeated + 'msg {}
impl<'msg, T> AsView for RepeatedMut<'msg, T>
diff --git a/rust/string.rs b/rust/string.rs
index 32421e5..7c75878 100644
--- a/rust/string.rs
+++ b/rust/string.rs
@@ -9,7 +9,7 @@
#![allow(dead_code)]
#![allow(unused)]
-use crate::__internal::Private;
+use crate::__internal::{Private, SealedInternal};
use crate::__runtime::{InnerProtoString, PtrAndLen, RawMessage};
use crate::{
utf8::Utf8Chunks, AsView, IntoProxied, IntoView, Mut, MutProxied, MutProxy, Optional, Proxied,
@@ -67,6 +67,8 @@
}
}
+impl SealedInternal for ProtoBytes {}
+
impl Proxied for ProtoBytes {
type View<'msg> = &'msg [u8];
}
@@ -127,6 +129,8 @@
}
}
+impl SealedInternal for &[u8] {}
+
impl<'msg> Proxy<'msg> for &'msg [u8] {}
impl AsView for &[u8] {
@@ -217,6 +221,8 @@
}
}
+impl SealedInternal for ProtoString {}
+
impl AsRef<[u8]> for ProtoString {
fn as_ref(&self) -> &[u8] {
self.inner.as_bytes()
@@ -241,6 +247,10 @@
}
}
+impl SealedInternal for &str {}
+
+impl SealedInternal for &ProtoStr {}
+
impl IntoProxied<ProtoString> for &str {
fn into_proxied(self, _private: Private) -> ProtoString {
ProtoString::from(self)
diff --git a/rust/upb.rs b/rust/upb.rs
index b90de06..cc4db52 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};
+use crate::__internal::{Enum, Private, SealedInternal};
use crate::{
IntoProxied, Map, MapIter, MapMut, MapView, Mut, ProtoBytes, ProtoStr, ProtoString, Proxied,
ProxiedInMapValue, ProxiedInRepeated, Repeated, RepeatedMut, RepeatedView, View,
@@ -64,6 +64,8 @@
#[doc(hidden)]
pub type SerializedData = upb::OwnedArenaBox<[u8]>;
+impl SealedInternal for SerializedData {}
+
impl IntoProxied<ProtoBytes> for SerializedData {
fn into_proxied(self, _private: Private) -> ProtoBytes {
ProtoBytes { inner: InnerProtoString(self) }