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

#ifndef PROTOBUF_HPB_HPB_H_
#define PROTOBUF_HPB_HPB_H_

#include <cstdint>
#include <type_traits>

#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/hpb/arena.h"
#include "google/protobuf/hpb/backend/upb/interop.h"
#include "google/protobuf/hpb/extension.h"
#include "google/protobuf/hpb/internal/internal.h"
#include "google/protobuf/hpb/internal/message_lock.h"
#include "google/protobuf/hpb/internal/template_help.h"
#include "google/protobuf/hpb/ptr.h"
#include "google/protobuf/hpb/status.h"
#include "upb/mini_table/extension.h"
#include "upb/wire/decode.h"

#ifdef HPB_BACKEND_UPB
#include "google/protobuf/hpb/backend/upb/upb.h"
#else
#error hpb backend must be specified
#endif

namespace hpb {

#ifdef HPB_BACKEND_UPB
namespace backend = ::hpb::internal::backend::upb;
#endif

template <typename T>
typename T::Proxy CreateMessage(hpb::Arena& arena) {
  return typename T::Proxy(upb_Message_New(T::minitable(), arena.ptr()),
                           arena.ptr());
}

template <typename T>
typename T::Proxy CloneMessage(Ptr<T> message, upb_Arena* arena) {
  return ::hpb::internal::PrivateAccess::Proxy<T>(
      ::hpb::internal::DeepClone(hpb::interop::upb::GetMessage(message),
                                 T::minitable(), arena),
      arena);
}

template <typename T>
void DeepCopy(Ptr<const T> source_message, Ptr<T> target_message) {
  static_assert(!std::is_const_v<T>);
  ::hpb::internal::DeepCopy(hpb::interop::upb::GetMessage(target_message),
                            hpb::interop::upb::GetMessage(source_message),
                            T::minitable(),
                            hpb::interop::upb::GetArena(target_message));
}

template <typename T>
void DeepCopy(Ptr<const T> source_message, T* target_message) {
  static_assert(!std::is_const_v<T>);
  DeepCopy(source_message, Ptr(target_message));
}

template <typename T>
void DeepCopy(const T* source_message, Ptr<T> target_message) {
  static_assert(!std::is_const_v<T>);
  DeepCopy(Ptr(source_message), target_message);
}

template <typename T>
void DeepCopy(const T* source_message, T* target_message) {
  static_assert(!std::is_const_v<T>);
  DeepCopy(Ptr(source_message), Ptr(target_message));
}

template <typename T>
void ClearMessage(hpb::internal::PtrOrRaw<T> message) {
  backend::ClearMessage(message);
}

template <typename T>
ABSL_MUST_USE_RESULT bool Parse(Ptr<T> message, absl::string_view bytes) {
  static_assert(!std::is_const_v<T>);
  upb_Message_Clear(hpb::interop::upb::GetMessage(message),
                    ::hpb::interop::upb::GetMiniTable(message));
  auto* arena = hpb::interop::upb::GetArena(message);
  return upb_Decode(bytes.data(), bytes.size(),
                    hpb::interop::upb::GetMessage(message),
                    ::hpb::interop::upb::GetMiniTable(message),
                    /* extreg= */ nullptr, /* options= */ 0,
                    arena) == kUpb_DecodeStatus_Ok;
}

template <typename T>
ABSL_MUST_USE_RESULT bool Parse(
    Ptr<T> message, absl::string_view bytes,
    const ::hpb::ExtensionRegistry& extension_registry) {
  static_assert(!std::is_const_v<T>);
  upb_Message_Clear(hpb::interop::upb::GetMessage(message),
                    ::hpb::interop::upb::GetMiniTable(message));
  auto* arena = hpb::interop::upb::GetArena(message);
  return upb_Decode(bytes.data(), bytes.size(),
                    hpb::interop::upb::GetMessage(message),
                    ::hpb::interop::upb::GetMiniTable(message),
                    /* extreg= */
                    ::hpb::internal::GetUpbExtensions(extension_registry),
                    /* options= */ 0, arena) == kUpb_DecodeStatus_Ok;
}

template <typename T>
ABSL_MUST_USE_RESULT bool Parse(
    T* message, absl::string_view bytes,
    const ::hpb::ExtensionRegistry& extension_registry) {
  static_assert(!std::is_const_v<T>);
  return Parse(Ptr(message, bytes, extension_registry));
}

template <typename T>
ABSL_MUST_USE_RESULT bool Parse(T* message, absl::string_view bytes) {
  static_assert(!std::is_const_v<T>);
  upb_Message_Clear(hpb::interop::upb::GetMessage(message),
                    ::hpb::interop::upb::GetMiniTable(message));
  auto* arena = hpb::interop::upb::GetArena(message);
  return upb_Decode(bytes.data(), bytes.size(),
                    hpb::interop::upb::GetMessage(message),
                    ::hpb::interop::upb::GetMiniTable(message),
                    /* extreg= */ nullptr, /* options= */ 0,
                    arena) == kUpb_DecodeStatus_Ok;
}

template <typename T>
absl::StatusOr<T> Parse(absl::string_view bytes, int options = 0) {
  T message;
  auto* arena = hpb::interop::upb::GetArena(&message);
  upb_DecodeStatus status =
      upb_Decode(bytes.data(), bytes.size(), message.msg(),
                 ::hpb::interop::upb::GetMiniTable(&message),
                 /* extreg= */ nullptr, /* options= */ 0, arena);
  if (status == kUpb_DecodeStatus_Ok) {
    return message;
  }
  return MessageDecodeError(status);
}

template <typename T>
absl::StatusOr<T> Parse(absl::string_view bytes,
                        const ::hpb::ExtensionRegistry& extension_registry,
                        int options = 0) {
  T message;
  auto* arena = hpb::interop::upb::GetArena(&message);
  upb_DecodeStatus status =
      upb_Decode(bytes.data(), bytes.size(), message.msg(),
                 ::hpb::interop::upb::GetMiniTable(&message),
                 ::hpb::internal::GetUpbExtensions(extension_registry),
                 /* options= */ 0, arena);
  if (status == kUpb_DecodeStatus_Ok) {
    return message;
  }
  return MessageDecodeError(status);
}

template <typename T>
absl::StatusOr<absl::string_view> Serialize(const T* message, hpb::Arena& arena,
                                            int options = 0) {
  return ::hpb::internal::Serialize(hpb::interop::upb::GetMessage(message),
                                    ::hpb::interop::upb::GetMiniTable(message),
                                    arena.ptr(), options);
}

template <typename T>
absl::StatusOr<absl::string_view> Serialize(Ptr<T> message, hpb::Arena& arena,
                                            int options = 0) {
  return ::hpb::internal::Serialize(hpb::interop::upb::GetMessage(message),
                                    ::hpb::interop::upb::GetMiniTable(message),
                                    arena.ptr(), options);
}

}  // namespace hpb

#endif  // PROTOBUF_HPB_HPB_H_
