// Protocol Buffers - Google's data interchange format
// Copyright 2024 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

#ifndef GOOGLE_PROTOBUF_HPB_BACKEND_UPB_INTEROP_H__
#define GOOGLE_PROTOBUF_HPB_BACKEND_UPB_INTEROP_H__

// The sole public header in hpb/backend/upb

#include <cstring>

#include "absl/strings/string_view.h"
#include "hpb/internal/internal.h"
#include "hpb/ptr.h"
#include "upb/base/string_view.h"
#include "upb/base/upcast.h"
#include "upb/mem/arena.h"
#include "upb/message/message.h"
#include "upb/mini_table/message.h"

namespace hpb::interop::upb {

/**
 * Moves ownership of a message created in a source arena.
 *
 * Utility function to provide a way to move ownership across languages or VMs.
 *
 * Warning: any minitable skew will incur arbitrary memory access. Ensuring
 * minitable compatibility is the responsibility of the caller.
 */
// TODO: b/365824801 - consider rename to OwnMessage
template <typename T>
T MoveMessage(upb_Message* msg, upb_Arena* arena) {
  return internal::PrivateAccess::InvokeConstructor<T>(msg, arena);
}

template <typename T>
const upb_MiniTable* GetMiniTable(const T*) {
  return T::minitable();
}

template <typename T>
const upb_MiniTable* GetMiniTable(Ptr<T>) {
  return T::minitable();
}

template <typename T>
auto* GetMessage(T&& message) {
  return internal::PrivateAccess::GetInternalMsg(std::forward<T>(message));
}

template <typename T>
upb_Arena* GetArena(Ptr<T> message) {
  return internal::PrivateAccess::GetInternalArena(message);
}

template <typename T>
upb_Arena* GetArena(T* message) {
  return internal::PrivateAccess::GetInternalArena(message);
}

template <typename T>
upb_Arena* UnwrapArena(T&& arena) {
  return internal::PrivateAccess::GetInternalUPBArena(std::forward<T>(arena));
}

/**
 * Creates a const Handle to a upb message.
 *
 * The supplied arena must outlive the hpb handle.
 * All messages reachable from from the upb message must
 * outlive the hpb handle.
 *
 * That is:
 * upb allows message M on arena A to point to message M' on
 * arena A'. As a user of hpb, you must guarantee that both A and A'
 * outlive M and M'. In practice, this is enforced by using upb::Fuse,
 * or manual tracking.
 *
 * The upb message must not be mutated directly while the handle is alive.
 *
 * T must match actual type of `msg`.
 * TODO: b/361596328 - revisit GetArena for CHandles
 * TODO: b/362743843 - consider passing in MiniTable to ensure match
 */
// REMARK: This overload will be deleted soon. Prefer the overloads that take in
// the CMessageType or MiniTable.
template <typename T>
typename T::CProxy MakeCHandle(const upb_Message* msg, upb_Arena* arena) {
  return internal::PrivateAccess::CProxy<T>(msg, arena);
}

/* Creates a Handle from a const upb message.
 *
 * The supplied arena must outlive the hpb handle.
 * All messages reachable from from the upb message must
 * outlive the hpb handle.
 */
template <typename T>
typename T::CProxy MakeCHandle(
    const typename internal::AssociatedUpbTypes<T>::CMessageType* msg,
    upb_Arena* arena) {
  return internal::PrivateAccess::CProxy<T>(UPB_UPCAST(msg), arena);
}

/**
 * Creates a Handle to a mutable upb message.
 *
 * The supplied arena must outlive the hpb handle.
 * All messages reachable from from the upb message must
 * outlive the hpb handle.
 */
// REMARK: This overload will be deleted soon. Prefer the overloads that take in
// the CMessageType or MiniTable.
template <typename T>
typename T::Proxy MakeHandle(upb_Message* msg, upb_Arena* arena) {
  return typename T::Proxy(msg, arena);
}

/* Creates a Handle from a mutable upb message.
 *
 * The supplied arena must outlive the hpb handle.
 * All messages reachable from from the upb message must
 * outlive the hpb handle.
 */
template <typename T>
typename T::Proxy MakeHandle(
    typename internal::AssociatedUpbTypes<T>::CMessageType* msg,
    upb_Arena* arena) {
  return internal::PrivateAccess::Proxy<T>(UPB_UPCAST(msg), arena);
}

/**
 * Creates a message in the given arena and returns a handle to it.
 *
 * The supplied arena must outlive the hpb handle.
 * All messages reachable from from the upb message must
 * outlive the hpb handle.
 */
template <typename T>
typename T::Proxy CreateMessage(upb_Arena* arena) {
  return internal::PrivateAccess::CreateMessage<T>(arena);
}

inline absl::string_view FromUpbStringView(upb_StringView str) {
  return absl::string_view(str.data, str.size);
}

inline upb_StringView CopyToUpbStringView(absl::string_view str,
                                          upb_Arena* arena) {
  const size_t str_size = str.size();
  char* buffer = static_cast<char*>(upb_Arena_Malloc(arena, str_size));
  memcpy(buffer, str.data(), str_size);
  return upb_StringView_FromDataAndSize(buffer, str_size);
}

}  // namespace hpb::interop::upb

#endif  // GOOGLE_PROTOBUF_HPB_BACKEND_UPB_INTEROP_H__
