//===-- ConstString.h -------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_UTILITY_CONSTSTRING_H
#define LLDB_UTILITY_CONSTSTRING_H

#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/YAMLTraits.h"

#include <stddef.h>

namespace lldb_private {
class Stream;
}
namespace llvm {
class raw_ostream;
}

namespace lldb_private {

/// \class ConstString ConstString.h "lldb/Utility/ConstString.h"
/// A uniqued constant string class.
///
/// Provides an efficient way to store strings as uniqued strings. After the
/// strings are uniqued, finding strings that are equal to one another is very
/// fast as just the pointers need to be compared. It also allows for many
/// common strings from many different sources to be shared to keep the memory
/// footprint low.
///
/// No reference counting is done on strings that are added to the string
/// pool, once strings are added they are in the string pool for the life of
/// the program.
class ConstString {
public:
  /// Default constructor
  ///
  /// Initializes the string to an empty string.
  ConstString() : m_string(nullptr) {}

  /// Copy constructor
  ///
  /// Copies the string value in \a rhs into this object.
  ///
  /// \param[in] rhs
  ///     Another string object to copy.
  ConstString(const ConstString &rhs) : m_string(rhs.m_string) {}

  explicit ConstString(const llvm::StringRef &s);

  /// Construct with C String value
  ///
  /// Constructs this object with a C string by looking to see if the
  /// C string already exists in the global string pool. If it doesn't
  /// exist, it is added to the string pool.
  ///
  /// \param[in] cstr
  ///     A NULL terminated C string to add to the string pool.
  explicit ConstString(const char *cstr);

  /// Construct with C String value with max length
  ///
  /// Constructs this object with a C string with a length. If \a max_cstr_len
  /// is greater than the actual length of the string, the string length will
  /// be truncated. This allows substrings to be created without the need to
  /// NULL terminate the string as it is passed into this function.
  ///
  /// \param[in] cstr
  ///     A pointer to the first character in the C string. The C
  ///     string can be NULL terminated in a buffer that contains
  ///     more characters than the length of the string, or the
  ///     string can be part of another string and a new substring
  ///     can be created.
  ///
  /// \param[in] max_cstr_len
  ///     The max length of \a cstr. If the string length of \a cstr
  ///     is less than \a max_cstr_len, then the string will be
  ///     truncated. If the string length of \a cstr is greater than
  ///     \a max_cstr_len, then only max_cstr_len bytes will be used
  ///     from \a cstr.
  explicit ConstString(const char *cstr, size_t max_cstr_len);

  /// Destructor
  ///
  /// Since constant string values are currently not reference counted, there
  /// isn't much to do here.
  ~ConstString() = default;

  /// C string equality binary predicate function object for ConstString
  /// objects.
  struct StringIsEqual {
    /// C equality test.
    ///
    /// Two C strings are equal when they are contained in ConstString objects
    /// when their pointer values are equal to each other.
    ///
    /// \return
    ///     Returns \b true if the C string in \a lhs is equal to
    ///     the C string value in \a rhs, \b false otherwise.
    bool operator()(const char *lhs, const char *rhs) const {
      return lhs == rhs;
    }
  };

  /// Convert to bool operator.
  ///
  /// This allows code to check a ConstString object to see if it contains a
  /// valid string using code such as:
  ///
  /// \code
  /// ConstString str(...);
  /// if (str)
  /// { ...
  /// \endcode
  ///
  /// \return
  ///     /b True this object contains a valid non-empty C string, \b
  ///     false otherwise.
  explicit operator bool() const { return !IsEmpty(); }

  /// Assignment operator
  ///
  /// Assigns the string in this object with the value from \a rhs.
  ///
  /// \param[in] rhs
  ///     Another string object to copy into this object.
  ///
  /// \return
  ///     A const reference to this object.
  ConstString operator=(ConstString rhs) {
    m_string = rhs.m_string;
    return *this;
  }

  /// Equal to operator
  ///
  /// Returns true if this string is equal to the string in \a rhs. This
  /// operation is very fast as it results in a pointer comparison since all
  /// strings are in a uniqued in a global string pool.
  ///
  /// \param[in] rhs
  ///     Another string object to compare this object to.
  ///
  /// \return
  ///     true if this object is equal to \a rhs.
  ///     false if this object is not equal to \a rhs.
  bool operator==(ConstString rhs) const {
    // We can do a pointer compare to compare these strings since they must
    // come from the same pool in order to be equal.
    return m_string == rhs.m_string;
  }

  /// Equal to operator against a non-ConstString value.
  ///
  /// Returns true if this string is equal to the string in \a rhs. This
  /// overload is usually slower than comparing against a ConstString value.
  /// However, if the rhs string not already a ConstString and it is impractical
  /// to turn it into a non-temporary variable, then this overload is faster.
  ///
  /// \param[in] rhs
  ///     Another string object to compare this object to.
  ///
  /// \return
  ///     \b true if this object is equal to \a rhs.
  ///     \b false if this object is not equal to \a rhs.
  bool operator==(const char *rhs) const {
    // ConstString differentiates between empty strings and nullptr strings, but
    // StringRef doesn't. Therefore we have to do this check manually now.
    if (m_string == nullptr && rhs != nullptr)
      return false;
    if (m_string != nullptr && rhs == nullptr)
      return false;

    return GetStringRef() == rhs;
  }

  /// Not equal to operator
  ///
  /// Returns true if this string is not equal to the string in \a rhs. This
  /// operation is very fast as it results in a pointer comparison since all
  /// strings are in a uniqued in a global string pool.
  ///
  /// \param[in] rhs
  ///     Another string object to compare this object to.
  ///
  /// \return
  ///     \b true if this object is not equal to \a rhs.
  ///     \b false if this object is equal to \a rhs.
  bool operator!=(ConstString rhs) const {
    return m_string != rhs.m_string;
  }

  /// Not equal to operator against a non-ConstString value.
  ///
  /// Returns true if this string is not equal to the string in \a rhs. This
  /// overload is usually slower than comparing against a ConstString value.
  /// However, if the rhs string not already a ConstString and it is impractical
  /// to turn it into a non-temporary variable, then this overload is faster.
  ///
  /// \param[in] rhs
  ///     Another string object to compare this object to.
  ///
  /// \return \b true if this object is not equal to \a rhs, false otherwise.
  bool operator!=(const char *rhs) const { return !(*this == rhs); }

  bool operator<(ConstString rhs) const;

  /// Get the string value as a C string.
  ///
  /// Get the value of the contained string as a NULL terminated C string
  /// value.
  ///
  /// If \a value_if_empty is nullptr, then nullptr will be returned.
  ///
  /// \return Returns \a value_if_empty if the string is empty, otherwise
  ///     the C string value contained in this object.
  const char *AsCString(const char *value_if_empty = nullptr) const {
    return (IsEmpty() ? value_if_empty : m_string);
  }

  /// Get the string value as a llvm::StringRef
  ///
  /// \return
  ///     Returns a new llvm::StringRef object filled in with the
  ///     needed data.
  llvm::StringRef GetStringRef() const {
    return llvm::StringRef(m_string, GetLength());
  }

  /// Get the string value as a C string.
  ///
  /// Get the value of the contained string as a NULL terminated C string
  /// value. Similar to the ConstString::AsCString() function, yet this
  /// function will always return nullptr if the string is not valid. So this
  /// function is a direct accessor to the string pointer value.
  ///
  /// \return
  ///     Returns nullptr the string is invalid, otherwise the C string
  ///     value contained in this object.
  const char *GetCString() const { return m_string; }

  /// Get the length in bytes of string value.
  ///
  /// The string pool stores the length of the string, so we can avoid calling
  /// strlen() on the pointer value with this function.
  ///
  /// \return
  ///     Returns the number of bytes that this string occupies in
  ///     memory, not including the NULL termination byte.
  size_t GetLength() const;

  /// Clear this object's state.
  ///
  /// Clear any contained string and reset the value to the empty string
  /// value.
  void Clear() { m_string = nullptr; }

  /// Equal to operator
  ///
  /// Returns true if this string is equal to the string in \a rhs. If case
  /// sensitive equality is tested, this operation is very fast as it results
  /// in a pointer comparison since all strings are in a uniqued in a global
  /// string pool.
  ///
  /// \param[in] lhs
  ///     The Left Hand Side const ConstString object reference.
  ///
  /// \param[in] rhs
  ///     The Right Hand Side const ConstString object reference.
  ///
  /// \param[in] case_sensitive
  ///     Case sensitivity. If true, case sensitive equality
  ///     will be tested, otherwise character case will be ignored
  ///
  /// \return \b true if this object is equal to \a rhs, \b false otherwise.
  static bool Equals(ConstString lhs, ConstString rhs,
                     const bool case_sensitive = true);

  /// Compare two string objects.
  ///
  /// Compares the C string values contained in \a lhs and \a rhs and returns
  /// an integer result.
  ///
  /// NOTE: only call this function when you want a true string
  /// comparison. If you want string equality use the, use the == operator as
  /// it is much more efficient. Also if you want string inequality, use the
  /// != operator for the same reasons.
  ///
  /// \param[in] lhs
  ///     The Left Hand Side const ConstString object reference.
  ///
  /// \param[in] rhs
  ///     The Right Hand Side const ConstString object reference.
  ///
  /// \param[in] case_sensitive
  ///     Case sensitivity of compare. If true, case sensitive compare
  ///     will be performed, otherwise character case will be ignored
  ///
  /// \return -1 if lhs < rhs, 0 if lhs == rhs, 1 if lhs > rhs
  static int Compare(ConstString lhs, ConstString rhs,
                     const bool case_sensitive = true);

  /// Dump the object description to a stream.
  ///
  /// Dump the string value to the stream \a s. If the contained string is
  /// empty, print \a value_if_empty to the stream instead. If \a
  /// value_if_empty is nullptr, then nothing will be dumped to the stream.
  ///
  /// \param[in] s
  ///     The stream that will be used to dump the object description.
  ///
  /// \param[in] value_if_empty
  ///     The value to dump if the string is empty. If nullptr, nothing
  ///     will be output to the stream.
  void Dump(Stream *s, const char *value_if_empty = nullptr) const;

  /// Dump the object debug description to a stream.
  ///
  /// \param[in] s
  ///     The stream that will be used to dump the object description.
  void DumpDebug(Stream *s) const;

  /// Test for empty string.
  ///
  /// \return
  ///     \b true if the contained string is empty.
  ///     \b false if the contained string is not empty.
  bool IsEmpty() const { return m_string == nullptr || m_string[0] == '\0'; }

  /// Test for null string.
  ///
  /// \return
  ///     \b true if there is no string associated with this instance.
  ///     \b false if there is a string associated with this instance.
  bool IsNull() const { return m_string == nullptr; }

  /// Set the C string value.
  ///
  /// Set the string value in the object by uniquing the \a cstr string value
  /// in our global string pool.
  ///
  /// If the C string already exists in the global string pool, it finds the
  /// current entry and returns the existing value. If it doesn't exist, it is
  /// added to the string pool.
  ///
  /// \param[in] cstr
  ///     A NULL terminated C string to add to the string pool.
  void SetCString(const char *cstr);

  void SetString(const llvm::StringRef &s);

  /// Set the C string value and its mangled counterpart.
  ///
  /// Object files and debug symbols often use mangled string to represent the
  /// linkage name for a symbol, function or global. The string pool can
  /// efficiently store these values and their counterparts so when we run
  /// into another instance of a mangled name, we can avoid calling the name
  /// demangler over and over on the same strings and then trying to unique
  /// them.
  ///
  /// \param[in] demangled
  ///     The demangled string to correlate with the \a mangled name.
  ///
  /// \param[in] mangled
  ///     The already uniqued mangled ConstString to correlate the
  ///     soon to be uniqued version of \a demangled.
  void SetStringWithMangledCounterpart(llvm::StringRef demangled,
                                       ConstString mangled);

  /// Retrieve the mangled or demangled counterpart for a mangled or demangled
  /// ConstString.
  ///
  /// Object files and debug symbols often use mangled string to represent the
  /// linkage name for a symbol, function or global. The string pool can
  /// efficiently store these values and their counterparts so when we run
  /// into another instance of a mangled name, we can avoid calling the name
  /// demangler over and over on the same strings and then trying to unique
  /// them.
  ///
  /// \param[in] counterpart
  ///     A reference to a ConstString object that might get filled in
  ///     with the demangled/mangled counterpart.
  ///
  /// \return
  ///     /b True if \a counterpart was filled in with the counterpart
  ///     /b false otherwise.
  bool GetMangledCounterpart(ConstString &counterpart) const;

  /// Set the C string value with length.
  ///
  /// Set the string value in the object by uniquing \a cstr_len bytes
  /// starting at the \a cstr string value in our global string pool. If trim
  /// is true, then \a cstr_len indicates a maximum length of the CString and
  /// if the actual length of the string is less, then it will be trimmed.
  ///
  /// If the C string already exists in the global string pool, it finds the
  /// current entry and returns the existing value. If it doesn't exist, it is
  /// added to the string pool.
  ///
  /// \param[in] cstr
  ///     A NULL terminated C string to add to the string pool.
  ///
  /// \param[in] cstr_len
  ///     The maximum length of the C string.
  void SetCStringWithLength(const char *cstr, size_t cstr_len);

  /// Set the C string value with the minimum length between \a fixed_cstr_len
  /// and the actual length of the C string. This can be used for data
  /// structures that have a fixed length to store a C string where the string
  /// might not be NULL terminated if the string takes the entire buffer.
  void SetTrimmedCStringWithLength(const char *cstr, size_t fixed_cstr_len);

  /// Get the memory cost of this object.
  ///
  /// Return the size in bytes that this object takes in memory. This returns
  /// the size in bytes of this object, which does not include any the shared
  /// string values it may refer to.
  ///
  /// \return
  ///     The number of bytes that this object occupies in memory.
  ///
  /// \see ConstString::StaticMemorySize ()
  size_t MemorySize() const { return sizeof(ConstString); }

  /// Get the size in bytes of the current global string pool.
  ///
  /// Reports the size in bytes of all shared C string values, containers and
  /// any other values as a byte size for the entire string pool.
  ///
  /// \return
  ///     The number of bytes that the global string pool occupies
  ///     in memory.
  static size_t StaticMemorySize();

protected:
  template <typename T> friend struct ::llvm::DenseMapInfo;
  /// Only used by DenseMapInfo.
  static ConstString FromStringPoolPointer(const char *ptr) {
    ConstString s;
    s.m_string = ptr;
    return s;
  };

  // Member variables
  const char *m_string;
};

/// Stream the string value \a str to the stream \a s
Stream &operator<<(Stream &s, ConstString str);

} // namespace lldb_private

namespace llvm {
template <> struct format_provider<lldb_private::ConstString> {
  static void format(const lldb_private::ConstString &CS, llvm::raw_ostream &OS,
                     llvm::StringRef Options);
};

/// DenseMapInfo implementation.
/// \{
template <> struct DenseMapInfo<lldb_private::ConstString> {
  static inline lldb_private::ConstString getEmptyKey() {
    return lldb_private::ConstString::FromStringPoolPointer(
        DenseMapInfo<const char *>::getEmptyKey());
  }
  static inline lldb_private::ConstString getTombstoneKey() {
    return lldb_private::ConstString::FromStringPoolPointer(
        DenseMapInfo<const char *>::getTombstoneKey());
  }
  static unsigned getHashValue(lldb_private::ConstString val) {
    return DenseMapInfo<const char *>::getHashValue(val.m_string);
  }
  static bool isEqual(lldb_private::ConstString LHS,
                      lldb_private::ConstString RHS) {
    return LHS == RHS;
  }
};
/// \}

namespace yaml {
template <> struct ScalarTraits<lldb_private::ConstString> {
  static void output(const lldb_private::ConstString &, void *, raw_ostream &);
  static StringRef input(StringRef, void *, lldb_private::ConstString &);
  static QuotingType mustQuote(StringRef S) { return QuotingType::Double; }
};
} // namespace yaml

inline raw_ostream &operator<<(raw_ostream &os, lldb_private::ConstString s) {
  os << s.GetStringRef();
  return os;
}
} // namespace llvm

LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ConstString)

#endif // LLDB_UTILITY_CONSTSTRING_H
