// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
#define GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__

#include <string>
#include <utility>

#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/common.h"
#include "google/protobuf/port.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/arenastring.h"
#include "google/protobuf/message_lite.h"

// Must be included last.
#include "google/protobuf/port_def.inc"

#ifdef SWIG
#error "You cannot SWIG proto headers"
#endif

namespace google {
namespace protobuf {

class Arena;

namespace internal {

// InlinedStringField wraps a std::string instance and exposes an API similar to
// ArenaStringPtr's wrapping of a std::string* instance.
//
// default_value parameters are taken for consistency with ArenaStringPtr, but
// are not used for most methods. With inlining, these should be removed from
// the generated binary.
//
// InlinedStringField has a donating mechanism that allows string buffer
// allocated on arena. A string is donated means both the string container and
// the data buffer are on arena. The donating mechanism here is similar to the
// one in ArenaStringPtr with some differences:
//
// When an InlinedStringField is constructed, the donating state is true. This
// is because the string container is directly stored in the message on the
// arena:
//
//   Construction: donated=true
//   Arena:
//   +-----------------------+
//   |Message foo:           |
//   | +-------------------+ |
//   | |InlinedStringField:| |
//   | | +-----+           | |
//   | | | | | |           | |
//   | | +-----+           | |
//   | +-------------------+ |
//   +-----------------------+
//
// When lvalue Set is called, the donating state is still true. String data will
// be allocated on the arena:
//
//   Lvalue Set: donated=true
//   Arena:
//   +-----------------------+
//   |Message foo:           |
//   | +-------------------+ |
//   | |InlinedStringField:| |
//   | | +-----+           | |
//   | | | | | |           | |
//   | | +|----+           | |
//   | +--|----------------+ |
//   |    V                  |
//   |  +----------------+   |
//   |  |'f','o','o',... |   |
//   |  +----------------+   |
//   +-----------------------+
//
// Some operations will undonate a donated string, including: Mutable,
// SetAllocated, Rvalue Set, and Swap with a non-donated string.
//
// For more details of the donating states transitions, go/pd-inlined-string.
class PROTOBUF_EXPORT InlinedStringField {
 public:
  InlinedStringField() { Init(); }
  inline void Init() { new (get_mutable()) std::string(); }
  // Add the dummy parameter just to make InlinedStringField(nullptr)
  // unambiguous.
  constexpr InlinedStringField(
      const ExplicitlyConstructed<std::string>* /*default_value*/,
      bool /*dummy*/)
      : value_{} {}
  explicit InlinedStringField(const std::string& default_value);
  explicit InlinedStringField(Arena* arena);
  ~InlinedStringField() { Destruct(); }

  // Lvalue Set. To save space, we pack the donating states of multiple
  // InlinedStringFields into an uint32_t `donating_states`. The `mask`
  // indicates the position of the bit for this InlinedStringField. `donated` is
  // whether this field is donated.
  //
  // The caller should guarantee that:
  //
  //   `donated == ((donating_states & ~mask) != 0)`
  //
  // This method never changes the `donating_states`.
  void Set(absl::string_view value, Arena* arena, bool donated,
           uint32_t* donating_states, uint32_t mask, MessageLite* msg);

  // Rvalue Set. If this field is donated, this method will undonate this field
  // by mutating the `donating_states` according to `mask`.
  void Set(std::string&& value, Arena* arena, bool donated,
           uint32_t* donating_states, uint32_t mask, MessageLite* msg);

  void Set(const char* str, ::google::protobuf::Arena* arena, bool donated,
           uint32_t* donating_states, uint32_t mask, MessageLite* msg);

  void Set(const char* str, size_t size, ::google::protobuf::Arena* arena, bool donated,
           uint32_t* donating_states, uint32_t mask, MessageLite* msg);

  template <typename RefWrappedType>
  void Set(std::reference_wrapper<RefWrappedType> const_string_ref,
           ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
           uint32_t mask, MessageLite* msg);

  void SetBytes(absl::string_view value, Arena* arena, bool donated,
                uint32_t* donating_states, uint32_t mask, MessageLite* msg);

  void SetBytes(std::string&& value, Arena* arena, bool donated,
                uint32_t* donating_states, uint32_t mask, MessageLite* msg);

  void SetBytes(const char* str, ::google::protobuf::Arena* arena, bool donated,
                uint32_t* donating_states, uint32_t mask, MessageLite* msg);

  void SetBytes(const void* p, size_t size, ::google::protobuf::Arena* arena,
                bool donated, uint32_t* donating_states, uint32_t mask,
                MessageLite* msg);

  template <typename RefWrappedType>
  void SetBytes(std::reference_wrapper<RefWrappedType> const_string_ref,
                ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
                uint32_t mask, MessageLite* msg);

  PROTOBUF_NDEBUG_INLINE void SetNoArena(absl::string_view value);
  PROTOBUF_NDEBUG_INLINE void SetNoArena(std::string&& value);

  // Basic accessors.
  PROTOBUF_NDEBUG_INLINE const std::string& Get() const { return GetNoArena(); }
  PROTOBUF_NDEBUG_INLINE const std::string& GetNoArena() const;

  // Mutable returns a std::string* instance that is heap-allocated. If this
  // field is donated, this method undonates this field by mutating the
  // `donating_states` according to `mask`, and copies the content of the
  // original string to the returning string.
  std::string* Mutable(Arena* arena, bool donated, uint32_t* donating_states,
                       uint32_t mask, MessageLite* msg);
  std::string* Mutable(const LazyString& default_value, Arena* arena,
                       bool donated, uint32_t* donating_states, uint32_t mask,
                       MessageLite* msg);

  // Mutable(nullptr_t) is an overload to explicitly support Mutable(nullptr)
  // calls used by the internal parser logic. This provides API equivalence with
  // ArenaStringPtr, while still protecting against calls with arena pointers.
  std::string* Mutable(std::nullptr_t);
  std::string* MutableNoCopy(std::nullptr_t);

  // Takes a std::string that is heap-allocated, and takes ownership. The
  // std::string's destructor is registered with the arena. Used to implement
  // set_allocated_<field> in generated classes.
  //
  // If this field is donated, this method undonates this field by mutating the
  // `donating_states` according to `mask`.
  void SetAllocated(const std::string* default_value, std::string* value,
                    Arena* arena, bool donated, uint32_t* donating_states,
                    uint32_t mask, MessageLite* msg);

  void SetAllocatedNoArena(const std::string* default_value,
                           std::string* value);

  // Release returns a std::string* instance that is heap-allocated and is not
  // Own()'d by any arena. If the field is not set, this returns nullptr. The
  // caller retains ownership. Clears this field back to nullptr state. Used to
  // implement release_<field>() methods on generated classes.
  PROTOBUF_NODISCARD std::string* Release(Arena* arena, bool donated);
  PROTOBUF_NODISCARD std::string* Release();

  // --------------------------------------------------------
  // Below functions will be removed in subsequent code change
  // --------------------------------------------------------
#ifdef DEPRECATED_METHODS_TO_BE_DELETED
  PROTOBUF_NODISCARD std::string* Release(const std::string*, Arena* arena,
                                          bool donated) {
    return Release(arena, donated);
  }

  PROTOBUF_NODISCARD std::string* ReleaseNonDefault(const std::string*,
                                                    Arena* arena) {
    return Release();
  }

  std::string* ReleaseNonDefaultNoArena(const std::string* default_value) {
    return Release();
  }

  void Set(const std::string*, absl::string_view value, Arena* arena,
           bool donated, uint32_t* donating_states, uint32_t mask,
           MessageLite* msg) {
    Set(value, arena, donated, donating_states, mask, msg);
  }

  void Set(const std::string*, std::string&& value, Arena* arena, bool donated,
           uint32_t* donating_states, uint32_t mask, MessageLite* msg) {
    Set(std::move(value), arena, donated, donating_states, mask, msg);
  }


  template <typename FirstParam>
  void Set(FirstParam, const char* str, ::google::protobuf::Arena* arena, bool donated,
           uint32_t* donating_states, uint32_t mask, MessageLite* msg) {
    Set(str, arena, donated, donating_states, mask, msg);
  }

  template <typename FirstParam>
  void Set(FirstParam p1, const char* str, size_t size, ::google::protobuf::Arena* arena,
           bool donated, uint32_t* donating_states, uint32_t mask,
           MessageLite* msg) {
    Set(str, size, arena, donated, donating_states, mask, msg);
  }

  template <typename FirstParam, typename RefWrappedType>
  void Set(FirstParam p1,
           std::reference_wrapper<RefWrappedType> const_string_ref,
           ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
           uint32_t mask, MessageLite* msg) {
    Set(const_string_ref, arena, donated, donating_states, mask, msg);
  }

  void SetBytes(const std::string*, absl::string_view value, Arena* arena,
                bool donated, uint32_t* donating_states, uint32_t mask,
                MessageLite* msg) {
    Set(value, arena, donated, donating_states, mask, msg);
  }


  void SetBytes(const std::string*, std::string&& value, Arena* arena,
                bool donated, uint32_t* donating_states, uint32_t mask,
                MessageLite* msg) {
    Set(std::move(value), arena, donated, donating_states, mask, msg);
  }

  template <typename FirstParam>
  void SetBytes(FirstParam p1, const char* str, ::google::protobuf::Arena* arena,
                bool donated, uint32_t* donating_states, uint32_t mask,
                MessageLite* msg) {
    SetBytes(str, arena, donated, donating_states, mask, msg);
  }

  template <typename FirstParam>
  void SetBytes(FirstParam p1, const void* p, size_t size,
                ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
                uint32_t mask, MessageLite* msg) {
    SetBytes(p, size, arena, donated, donating_states, mask, msg);
  }

  template <typename FirstParam, typename RefWrappedType>
  void SetBytes(FirstParam p1,
                std::reference_wrapper<RefWrappedType> const_string_ref,
                ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
                uint32_t mask, MessageLite* msg) {
    SetBytes(const_string_ref.get(), arena, donated, donating_states, mask,
             msg);
  }

  void SetNoArena(const std::string*, absl::string_view value) {
    SetNoArena(value);
  }
  void SetNoArena(const std::string*, std::string&& value) {
    SetNoArena(std::move(value));
  }

  std::string* Mutable(ArenaStringPtr::EmptyDefault, Arena* arena, bool donated,
                       uint32_t* donating_states, uint32_t mask,
                       MessageLite* msg) {
    return Mutable(arena, donated, donating_states, mask, msg);
  }

  PROTOBUF_NDEBUG_INLINE std::string* MutableNoArenaNoDefault(
      const std::string* /*default_value*/) {
    return MutableNoCopy(nullptr);
  }

#endif  // DEPRECATED_METHODS_TO_BE_DELETED

  // Arena-safety semantics: this is guarded by the logic in
  // Swap()/UnsafeArenaSwap() at the message level, so this method is
  // 'unsafe' if called directly.
  inline PROTOBUF_NDEBUG_INLINE static void InternalSwap(
      InlinedStringField* lhs, Arena* lhs_arena, bool lhs_arena_dtor_registered,
      MessageLite* lhs_msg,  //
      InlinedStringField* rhs, Arena* rhs_arena, bool rhs_arena_dtor_registered,
      MessageLite* rhs_msg);

  // Frees storage (if not on an arena).
  PROTOBUF_NDEBUG_INLINE void Destroy(const std::string* default_value,
                                      Arena* arena) {
    if (arena == nullptr) {
      DestroyNoArena(default_value);
    }
  }
  PROTOBUF_NDEBUG_INLINE void DestroyNoArena(const std::string* default_value);

  // Clears content, but keeps allocated std::string, to avoid the overhead of
  // heap operations. After this returns, the content (as seen by the user) will
  // always be the empty std::string.
  PROTOBUF_NDEBUG_INLINE void ClearToEmpty() { ClearNonDefaultToEmpty(); }
  PROTOBUF_NDEBUG_INLINE void ClearNonDefaultToEmpty() {
    get_mutable()->clear();
  }

  // Clears content, but keeps allocated std::string if arena != nullptr, to
  // avoid the overhead of heap operations. After this returns, the content (as
  // seen by the user) will always be equal to |default_value|.
  void ClearToDefault(const LazyString& default_value, Arena* arena,
                      bool donated);

  // Generated code / reflection only! Returns a mutable pointer to the string.
  PROTOBUF_NDEBUG_INLINE std::string* UnsafeMutablePointer();

  // InlinedStringField doesn't have things like the `default_value` pointer in
  // ArenaStringPtr.
  static constexpr bool IsDefault() { return false; }
  static constexpr bool IsDefault(const std::string*) { return false; }

 private:
  void Destruct() { get_mutable()->~basic_string(); }

  PROTOBUF_NDEBUG_INLINE std::string* get_mutable();
  PROTOBUF_NDEBUG_INLINE const std::string* get_const() const;

  alignas(std::string) char value_[sizeof(std::string)];

  std::string* MutableSlow(::google::protobuf::Arena* arena, bool donated,
                           uint32_t* donating_states, uint32_t mask,
                           MessageLite* msg);


  // When constructed in an Arena, we want our destructor to be skipped.
  friend class ::google::protobuf::Arena;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
};

inline std::string* InlinedStringField::get_mutable() {
  return reinterpret_cast<std::string*>(&value_);
}

inline const std::string* InlinedStringField::get_const() const {
  return reinterpret_cast<const std::string*>(&value_);
}

inline InlinedStringField::InlinedStringField(
    const std::string& default_value) {
  new (get_mutable()) std::string(default_value);
}


inline InlinedStringField::InlinedStringField(Arena* /*arena*/) { Init(); }

inline const std::string& InlinedStringField::GetNoArena() const {
  return *get_const();
}

inline void InlinedStringField::SetAllocatedNoArena(
    const std::string* /*default_value*/, std::string* value) {
  if (value == nullptr) {
    // Currently, inlined string field can't have non empty default.
    get_mutable()->clear();
  } else {
    get_mutable()->assign(std::move(*value));
    delete value;
  }
}

inline void InlinedStringField::DestroyNoArena(const std::string*) {
  // This is invoked from the generated message's ArenaDtor, which is used to
  // clean up objects not allocated on the Arena.
  this->~InlinedStringField();
}

inline void InlinedStringField::SetNoArena(absl::string_view value) {
  get_mutable()->assign(value.data(), value.length());
}

inline void InlinedStringField::SetNoArena(std::string&& value) {
  get_mutable()->assign(std::move(value));
}

// Caller should make sure rhs_arena allocated rhs, and lhs_arena allocated lhs.
inline PROTOBUF_NDEBUG_INLINE void InlinedStringField::InternalSwap(
    InlinedStringField* lhs, Arena* lhs_arena, bool lhs_arena_dtor_registered,
    MessageLite* lhs_msg,  //
    InlinedStringField* rhs, Arena* rhs_arena, bool rhs_arena_dtor_registered,
    MessageLite* rhs_msg) {
#ifdef GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
  lhs->get_mutable()->swap(*rhs->get_mutable());
  if (!lhs_arena_dtor_registered && rhs_arena_dtor_registered) {
    lhs_msg->OnDemandRegisterArenaDtor(lhs_arena);
  } else if (lhs_arena_dtor_registered && !rhs_arena_dtor_registered) {
    rhs_msg->OnDemandRegisterArenaDtor(rhs_arena);
  }
#else
  (void)lhs_arena;
  (void)rhs_arena;
  (void)lhs_arena_dtor_registered;
  (void)rhs_arena_dtor_registered;
  (void)lhs_msg;
  (void)rhs_msg;
  lhs->get_mutable()->swap(*rhs->get_mutable());
#endif
}

inline void InlinedStringField::Set(absl::string_view value, Arena* arena,
                                    bool donated, uint32_t* /*donating_states*/,
                                    uint32_t /*mask*/, MessageLite* /*msg*/) {
  (void)arena;
  (void)donated;
  SetNoArena(value);
}

inline void InlinedStringField::Set(const char* str, ::google::protobuf::Arena* arena,
                                    bool donated, uint32_t* donating_states,
                                    uint32_t mask, MessageLite* msg) {
  Set(absl::string_view(str), arena, donated, donating_states, mask, msg);
}

inline void InlinedStringField::Set(const char* str, size_t size,
                                    ::google::protobuf::Arena* arena, bool donated,
                                    uint32_t* donating_states, uint32_t mask,
                                    MessageLite* msg) {
  Set(absl::string_view{str, size}, arena, donated, donating_states, mask, msg);
}

inline void InlinedStringField::SetBytes(absl::string_view value, Arena* arena,
                                         bool donated,
                                         uint32_t* donating_states,
                                         uint32_t mask, MessageLite* msg) {
  Set(value, arena, donated, donating_states, mask, msg);
}

inline void InlinedStringField::SetBytes(std::string&& value, Arena* arena,
                                         bool donated,
                                         uint32_t* donating_states,
                                         uint32_t mask, MessageLite* msg) {
  Set(std::move(value), arena, donated, donating_states, mask, msg);
}

inline void InlinedStringField::SetBytes(const char* str,
                                         ::google::protobuf::Arena* arena, bool donated,
                                         uint32_t* donating_states,
                                         uint32_t mask, MessageLite* msg) {
  Set(str, arena, donated, donating_states, mask, msg);
}

inline void InlinedStringField::SetBytes(const void* p, size_t size,
                                         ::google::protobuf::Arena* arena, bool donated,
                                         uint32_t* donating_states,
                                         uint32_t mask, MessageLite* msg) {
  Set(static_cast<const char*>(p), size, arena, donated, donating_states, mask,
      msg);
}

template <typename RefWrappedType>
inline void InlinedStringField::Set(
    std::reference_wrapper<RefWrappedType> const_string_ref,
    ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
    uint32_t mask, MessageLite* msg) {
  Set(const_string_ref.get(), arena, donated, donating_states, mask, msg);
}

template <typename RefWrappedType>
inline void InlinedStringField::SetBytes(
    std::reference_wrapper<RefWrappedType> const_string_ref,
    ::google::protobuf::Arena* arena, bool donated, uint32_t* donating_states,
    uint32_t mask, MessageLite* msg) {
  Set(const_string_ref.get(), arena, donated, donating_states, mask, msg);
}

inline std::string* InlinedStringField::UnsafeMutablePointer() {
  return get_mutable();
}

inline std::string* InlinedStringField::Mutable(std::nullptr_t) {
  return get_mutable();
}

inline std::string* InlinedStringField::MutableNoCopy(std::nullptr_t) {
  return get_mutable();
}

}  // namespace internal
}  // namespace protobuf
}  // namespace google

#include "google/protobuf/port_undef.inc"

#endif  // GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
