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

/// 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 + 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();
    ///   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 googletest::prelude::*;
    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_that!(my_view.val(), eq(&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_that!(my_proxied.val, eq(val_after_set));
        assert_that!(my_proxied.val, eq("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_that!(my_proxied.as_view().val(), eq("hello"));

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

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