// 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

//! Operating on borrowed data owned by a message is a central concept in
//! Protobuf (and Rust in general). The way this is normally accomplished in
//! Rust is to pass around references and operate on those. Unfortunately,
//! references come with two major drawbacks:
//!
//! * We must store the value somewhere in the memory to create a reference to
//!   it. The value must be readable by a single load. However for Protobuf
//!   fields it happens that the actual memory representation of a value differs
//!   from what users expect and it is an implementation detail that can change
//!   as more optimizations are implemented. For example, rarely accessed
//!   `int64` fields can be represented in a packed format with 32 bits for the
//!   value in the common case. Or, a single logical value can be spread across
//!   multiple memory locations. For example, presence information for all the
//!   fields in a protobuf message is centralized in a bitset.
//! * We cannot store extra data on the reference that might be necessary for
//!   correctly manipulating it (and custom-metadata DSTs do not exist yet in
//!   Rust). Concretely, messages, string, bytes, and repeated fields in UPB
//!   need to carry around an arena parameter separate from the data pointer to
//!   enable mutation (for example adding an element to a repeated field) or
//!   potentially to enable optimizations (for example referencing a string
//!   value using a Cord-like type instead of copying it if the source and
//!   target messages are on the same arena already). Mutable references to
//!   messages have one additional drawback: Rust allows users to
//!   indiscriminately run a bytewise swap() on mutable references, which could
//!   result in pointers to the wrong arena winding up on a message. For
//!   example, imagine swapping a submessage across two root messages allocated
//!   on distinct arenas A and B; after the swap, the message allocated in A may
//!   contain pointers from B by way of the submessage, because the swap does
//!   not know to fix up those pointers as needed. The C++ API uses
//!   message-owned arenas, and this ends up resembling self-referential types,
//!   which need `Pin` in order to be sound. However, `Pin` has much stronger
//!   guarantees than we need to uphold.
//!
//! These drawbacks put the "idiomatic Rust" goal in conflict with the
//! "performance", "evolvability", and "safety" goals. Given the project design
//! priorities we decided to not use plain Rust references. Instead, we
//! implemented the concept of "proxy" types. Proxy types are a reference-like
//! indirection between the user and the internal memory representation.

use crate::RepeatedMut;
use crate::__internal::Private;
use crate::repeated::ProxiedInRepeated;
use std::fmt::Debug;
use std::marker::{Send, Sync};

/// A type that can be accessed through a reference-like proxy.
///
/// An instance of a `Proxied` can be accessed
/// immutably via `Proxied::View` and mutably via `Proxied::Mut`.
///
/// All Protobuf field types implement `Proxied`.
pub trait Proxied {
    /// The proxy type that provides shared access to a `T`, like a `&'msg T`.
    ///
    /// Most code should use the type alias [`View`].
    type View<'msg>: ViewProxy<'msg, Proxied = Self> + Copy + Send + SettableValue<Self>
    where
        Self: 'msg;

    /// The proxy type that provides exclusive mutable access to a `T`, like a
    /// `&'msg mut T`.
    ///
    /// Most code should use the type alias [`Mut`].
    type Mut<'msg>: MutProxy<'msg, Proxied = Self>
    where
        Self: 'msg;
}

/// A proxy type that provides shared access to a `T`, like a `&'msg T`.
///
/// This is more concise than fully spelling the associated type.
#[allow(dead_code)]
pub type View<'msg, T> = <T as Proxied>::View<'msg>;

/// A proxy type that provides exclusive mutable access to a `T`, like a
/// `&'msg mut T`.
///
/// This is more concise than fully spelling the associated type.
#[allow(dead_code)]
pub type Mut<'msg, T> = <T as Proxied>::Mut<'msg>;

/// Declares conversion operations common to all views.
///
/// This trait is intentionally made non-object-safe to prevent a potential
/// future incompatible change.
pub trait ViewProxy<'msg>: 'msg + Sized + Sync + Unpin + Sized + Debug {
    type Proxied: 'msg + Proxied + ?Sized;

    /// Converts a borrow into a `View` with the lifetime of that borrow.
    ///
    /// In non-generic code we don't need to use `as_view` because the proxy
    /// types are covariant over `'msg`. However, generic code conservatively
    /// treats `'msg` as [invariant], therefore we need to call
    /// `as_view` to explicitly perform the operation that in concrete code
    /// coercion would perform implicitly.
    ///
    /// For example, the call to `.as_view()` in the following snippet
    /// wouldn't be necessary in concrete code:
    /// ```
    /// fn reborrow<'a, 'b, T>(x: &'b View<'a, T>) -> View<'b, T>
    /// where 'a: 'b, T: Proxied
    /// {
    ///   x.as_view()
    /// }
    /// ```
    ///
    /// [invariant]: https://doc.rust-lang.org/nomicon/subtyping.html#variance
    fn as_view(&self) -> View<'_, Self::Proxied>;

    /// Converts into a `View` with a potentially shorter lifetime.
    ///
    /// In non-generic code we don't need to use `into_view` because the proxy
    /// types are covariant over `'msg`. However, generic code conservatively
    /// treats `'msg` as [invariant], therefore we need to call
    /// `into_view` to explicitly perform the operation that in concrete
    /// code coercion would perform implicitly.
    ///
    /// ```
    /// fn reborrow_generic_view_into_view<'a, 'b, T>(
    ///     x: View<'a, T>,
    ///     y: View<'b, T>,
    /// ) -> [View<'b, T>; 2]
    /// where
    ///     T: Proxied,
    ///     'a: 'b,
    /// {
    ///     // `[x, y]` fails to compile because `'a` is not the same as `'b` and the `View`
    ///     // lifetime parameter is (conservatively) invariant.
    ///     // `[x.as_view(), y]` fails because that borrow cannot outlive `'b`.
    ///     [x.into_view(), y]
    /// }
    /// ```
    ///
    /// [invariant]: https://doc.rust-lang.org/nomicon/subtyping.html#variance
    fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
    where
        'msg: 'shorter;
}

/// Declares operations common to all mutators.
///
/// This trait is intentionally made non-object-safe to prevent a potential
/// future incompatible change.
pub trait MutProxy<'msg>: ViewProxy<'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
    /// multiple times - if the result of `get` is not living long enough
    /// for your use, use that instead.
    fn get(&self) -> View<'_, Self::Proxied> {
        self.as_view()
    }

    /// Sets this field to the given `val`.
    ///
    /// Any borrowed data from `val` will be cloned.
    fn set(&mut self, val: impl SettableValue<Self::Proxied>) {
        val.set_on(Private, self.as_mut())
    }

    /// Converts a borrow into a `Mut` with the lifetime of that borrow.
    ///
    /// This function enables calling multiple methods consuming `self`, for
    /// example:
    ///
    /// ```ignore
    ///   let mut sub: Mut<SubMsg> = msg.submsg_mut().or_default();
    ///   sub.as_mut().field_x_mut().set(10);  // field_x_mut is fn(self)
    ///   sub.field_y_mut().set(20);  // `sub` is now consumed
    /// ```
    ///
    /// `as_mut` is also useful in generic code to explicitly perform the
    /// operation that in concrete code coercion would perform implicitly.
    fn as_mut(&mut self) -> Mut<'_, Self::Proxied>;

    /// Converts into a `Mut` with a potentially shorter lifetime.
    ///
    /// In non-generic code we don't need to use `into_mut` because the proxy
    /// types are covariant over `'msg`. However, generic code conservatively
    /// treats `'msg` as [invariant], therefore we need to call
    /// `into_mut` to explicitly perform the operation that in concrete code
    /// coercion would perform implicitly.
    ///
    /// ```
    /// fn reborrow_generic_mut_into_mut<'a, 'b, T>(x: Mut<'a, T>, y: Mut<'b, T>) -> [Mut<'b, T>; 2]
    /// where
    ///     T: Proxied,
    ///     'a: 'b,
    /// {
    ///     // `[x, y]` fails to compile because `'a` is not the same as `'b` and the `Mut`
    ///     // lifetime parameter is (conservatively) invariant.
    ///     // `[x.as_mut(), y]` fails because that borrow cannot outlive `'b`.
    ///     [x.into_mut(), y]
    /// }
    /// ```
    ///
    /// [invariant]: https://doc.rust-lang.org/nomicon/subtyping.html#variance
    fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied>
    where
        'msg: 'shorter;
}

// TODO: move this to `optional.rs` as it's only used for optionals
/// `Proxied` types that can be optionally set or unset.
///
/// All scalar and message types implement `ProxiedWithPresence`, while repeated
/// types don't.
pub trait ProxiedWithPresence: Proxied {
    /// The data necessary to store a present field mutator proxying `Self`.
    /// This is the contents of `PresentField<'msg, Self>`.
    type PresentMutData<'msg>: MutProxy<'msg, Proxied = Self>;

    /// The data necessary to store an absent field mutator proxying `Self`.
    /// This is the contents of `AbsentField<'msg, Self>`.
    type AbsentMutData<'msg>: ViewProxy<'msg, Proxied = Self>;

    /// Clears a present field.
    fn clear_present_field(present_mutator: Self::PresentMutData<'_>) -> Self::AbsentMutData<'_>;

    /// Sets an absent field to its default value.
    ///
    /// This can be more efficient than setting with a default value, e.g.
    /// a default submessage could share resources with the parent message.
    fn set_absent_to_default(absent_mutator: Self::AbsentMutData<'_>) -> Self::PresentMutData<'_>;
}

/// Values that can be used to set a field of `T`.
pub trait SettableValue<T>: Sized
where
    T: Proxied + ?Sized,
{
    /// Consumes `self` to set the given mutator to the value of `self`.
    #[doc(hidden)]
    fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, T>)
    where
        T: 'msg;

    /// Consumes `self` and `absent_mutator` to set the given empty field to
    /// the value of `self`.
    #[doc(hidden)]
    fn set_on_absent(
        self,
        _private: Private,
        absent_mutator: T::AbsentMutData<'_>,
    ) -> T::PresentMutData<'_>
    where
        T: ProxiedWithPresence,
    {
        let mut present = T::set_absent_to_default(absent_mutator);
        self.set_on(Private, present.as_mut());
        present
    }

    /// Consumes `self` and `present_mutator` to set the given present field
    /// to the value of `self`.
    #[doc(hidden)]
    fn set_on_present(self, _private: Private, mut present_mutator: T::PresentMutData<'_>)
    where
        T: ProxiedWithPresence,
    {
        self.set_on(Private, present_mutator.as_mut())
    }

    /// Consumes `self` and `repeated_mutator` to set the value at the
    /// given index to the value of `self`.
    ///
    /// # Safety
    /// `index` must be less than `repeated_mutator.len()`
    #[doc(hidden)]
    unsafe fn set_on_repeated_unchecked(
        self,
        _private: Private,
        mut _repeated_mutator: RepeatedMut<T>,
        _index: usize,
    ) where
        T: ProxiedInRepeated,
    {
        unimplemented!()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::borrow::Cow;

    #[derive(Debug, Default, PartialEq)]
    struct MyProxied {
        val: String,
    }

    impl MyProxied {
        fn as_view(&self) -> View<'_, Self> {
            MyProxiedView { my_proxied_ref: self }
        }

        fn as_mut(&mut self) -> Mut<'_, Self> {
            MyProxiedMut { my_proxied_ref: self }
        }
    }

    impl Proxied for MyProxied {
        type View<'msg> = MyProxiedView<'msg>;
        type Mut<'msg> = MyProxiedMut<'msg>;
    }

    #[derive(Debug, Clone, Copy)]
    struct MyProxiedView<'msg> {
        my_proxied_ref: &'msg MyProxied,
    }

    impl MyProxiedView<'_> {
        fn val(&self) -> &str {
            &self.my_proxied_ref.val
        }
    }

    impl<'msg> ViewProxy<'msg> for MyProxiedView<'msg> {
        type Proxied = MyProxied;

        fn as_view(&self) -> View<'msg, MyProxied> {
            *self
        }

        fn into_view<'shorter>(self) -> View<'shorter, MyProxied>
        where
            'msg: 'shorter,
        {
            self
        }
    }

    #[derive(Debug)]
    struct MyProxiedMut<'msg> {
        my_proxied_ref: &'msg mut MyProxied,
    }

    impl<'msg> ViewProxy<'msg> for MyProxiedMut<'msg> {
        type Proxied = MyProxied;

        fn as_view(&self) -> View<'_, MyProxied> {
            MyProxiedView { my_proxied_ref: self.my_proxied_ref }
        }
        fn into_view<'shorter>(self) -> View<'shorter, MyProxied>
        where
            'msg: 'shorter,
        {
            MyProxiedView { my_proxied_ref: self.my_proxied_ref }
        }
    }

    impl<'msg> MutProxy<'msg> for MyProxiedMut<'msg> {
        fn as_mut(&mut self) -> Mut<'_, MyProxied> {
            MyProxiedMut { my_proxied_ref: self.my_proxied_ref }
        }

        fn into_mut<'shorter>(self) -> Mut<'shorter, MyProxied>
        where
            'msg: 'shorter,
        {
            self
        }
    }

    impl SettableValue<MyProxied> for MyProxiedView<'_> {
        fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, MyProxied>)
        where
            MyProxied: 'msg,
        {
            mutator.my_proxied_ref.val = self.my_proxied_ref.val.clone();
        }
    }

    impl SettableValue<MyProxied> for String {
        fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, MyProxied>)
        where
            MyProxied: 'msg,
        {
            mutator.my_proxied_ref.val = self;
        }
    }

    impl SettableValue<MyProxied> for &'_ str {
        fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, MyProxied>)
        where
            MyProxied: 'msg,
        {
            mutator.my_proxied_ref.val.replace_range(.., self);
        }
    }

    impl SettableValue<MyProxied> for Cow<'_, str> {
        fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, MyProxied>)
        where
            MyProxied: 'msg,
        {
            match self {
                Cow::Owned(x) => <String as SettableValue<MyProxied>>::set_on(x, Private, mutator),
                Cow::Borrowed(x) => <&str as SettableValue<MyProxied>>::set_on(x, Private, mutator),
            }
        }
    }

    #[test]
    fn test_as_view() {
        let my_proxied = MyProxied { val: "Hello World".to_string() };

        let my_view = my_proxied.as_view();

        assert_eq!(my_view.val(), my_proxied.val);
    }

    #[test]
    fn test_as_mut() {
        let mut my_proxied = MyProxied { val: "Hello World".to_string() };

        let mut my_mut = my_proxied.as_mut();
        my_mut.set("Hello indeed".to_string());

        let val_after_set = my_mut.as_view().val().to_string();
        assert_eq!(my_proxied.val, val_after_set);
        assert_eq!(my_proxied.val, "Hello indeed");
    }

    fn reborrow_mut_into_view<'msg>(x: Mut<'msg, MyProxied>) -> View<'msg, MyProxied> {
        // x.as_view() fails to compile with:
        //   `ERROR: attempt to return function-local borrowed content`
        x.into_view() // OK: we return the same lifetime as we got in.
    }

    #[test]
    fn test_mut_into_view() {
        let mut my_proxied = MyProxied { val: "Hello World".to_string() };
        reborrow_mut_into_view(my_proxied.as_mut());
    }

    fn require_unified_lifetimes<'msg>(_x: Mut<'msg, MyProxied>, _y: View<'msg, MyProxied>) {}

    #[test]
    fn test_require_unified_lifetimes() {
        let mut my_proxied = MyProxied { val: "Hello1".to_string() };
        let my_mut = my_proxied.as_mut();

        {
            let other_proxied = MyProxied { val: "Hello2".to_string() };
            let other_view = other_proxied.as_view();
            require_unified_lifetimes(my_mut, other_view);
        }
    }

    fn reborrow_generic_as_view<'a, 'b, T>(
        x: &'b mut Mut<'a, T>,
        y: &'b View<'a, T>,
    ) -> [View<'b, T>; 2]
    where
        T: Proxied,
        'a: 'b,
    {
        // `[x, y]` fails to compile because `'a` is not the same as `'b` and the `View`
        // lifetime parameter is (conservatively) invariant.
        [x.as_view(), y.as_view()]
    }

    #[test]
    fn test_reborrow_generic_as_view() {
        let mut my_proxied = MyProxied { val: "Hello1".to_string() };
        let mut my_mut = my_proxied.as_mut();
        let my_ref = &mut my_mut;

        {
            let other_proxied = MyProxied { val: "Hello2".to_string() };
            let other_view = other_proxied.as_view();
            reborrow_generic_as_view::<MyProxied>(my_ref, &other_view);
        }
    }

    fn reborrow_generic_view_into_view<'a, 'b, T>(
        x: View<'a, T>,
        y: View<'b, T>,
    ) -> [View<'b, T>; 2]
    where
        T: Proxied,
        'a: 'b,
    {
        // `[x, y]` fails to compile because `'a` is not the same as `'b` and the `View`
        // lifetime parameter is (conservatively) invariant.
        // `[x.as_view(), y]` fails because that borrow cannot outlive `'b`.
        [x.into_view(), y]
    }

    #[test]
    fn test_reborrow_generic_into_view() {
        let my_proxied = MyProxied { val: "Hello1".to_string() };
        let my_view = my_proxied.as_view();

        {
            let other_proxied = MyProxied { val: "Hello2".to_string() };
            let other_view = other_proxied.as_view();
            reborrow_generic_view_into_view::<MyProxied>(my_view, other_view);
        }
    }

    fn reborrow_generic_mut_into_view<'a, 'b, T>(x: Mut<'a, T>, y: View<'b, T>) -> [View<'b, T>; 2]
    where
        T: Proxied,
        'a: 'b,
    {
        [x.into_view(), y]
    }

    #[test]
    fn test_reborrow_generic_mut_into_view() {
        let mut my_proxied = MyProxied { val: "Hello1".to_string() };
        let my_mut = my_proxied.as_mut();

        {
            let other_proxied = MyProxied { val: "Hello2".to_string() };
            let other_view = other_proxied.as_view();
            reborrow_generic_mut_into_view::<MyProxied>(my_mut, other_view);
        }
    }

    fn reborrow_generic_mut_into_mut<'a, 'b, T>(x: Mut<'a, T>, y: Mut<'b, T>) -> [Mut<'b, T>; 2]
    where
        T: Proxied,
        'a: 'b,
    {
        // `[x, y]` fails to compile because `'a` is not the same as `'b` and the `Mut`
        // lifetime parameter is (conservatively) invariant.
        // `[x.as_mut(), y]` fails because that borrow cannot outlive `'b`.
        [x.into_mut(), y]
    }

    #[test]
    fn test_reborrow_generic_mut_into_mut() {
        let mut my_proxied = MyProxied { val: "Hello1".to_string() };
        let my_mut = my_proxied.as_mut();

        {
            let mut other_proxied = MyProxied { val: "Hello2".to_string() };
            let other_mut = other_proxied.as_mut();
            // No need to reborrow, even though lifetime of &other_view is different
            // than the lifetiem of my_ref. Rust references are covariant over their
            // lifetime.
            reborrow_generic_mut_into_mut::<MyProxied>(my_mut, other_mut);
        }
    }

    #[test]
    fn test_set() {
        let mut my_proxied = MyProxied::default();
        my_proxied.as_mut().set("hello");
        assert_eq!(my_proxied.as_view().val(), "hello");

        my_proxied.as_mut().set(String::from("hello2"));
        assert_eq!(my_proxied.as_view().val(), "hello2");

        my_proxied.as_mut().set(Cow::Borrowed("hello3"));
        assert_eq!(my_proxied.as_view().val(), "hello3");
    }
}
