// 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 #include #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::Proxy CreateMessage(hpb::Arena& arena) { return typename T::Proxy(upb_Message_New(T::minitable(), arena.ptr()), arena.ptr()); } template typename T::Proxy CloneMessage(Ptr message, upb_Arena* arena) { return ::hpb::internal::PrivateAccess::Proxy( ::hpb::internal::DeepClone(hpb::interop::upb::GetMessage(message), T::minitable(), arena), arena); } template void DeepCopy(Ptr source_message, Ptr target_message) { static_assert(!std::is_const_v); ::hpb::internal::DeepCopy(hpb::interop::upb::GetMessage(target_message), hpb::interop::upb::GetMessage(source_message), T::minitable(), hpb::interop::upb::GetArena(target_message)); } template void DeepCopy(Ptr source_message, T* target_message) { static_assert(!std::is_const_v); DeepCopy(source_message, Ptr(target_message)); } template void DeepCopy(const T* source_message, Ptr target_message) { static_assert(!std::is_const_v); DeepCopy(Ptr(source_message), target_message); } template void DeepCopy(const T* source_message, T* target_message) { static_assert(!std::is_const_v); DeepCopy(Ptr(source_message), Ptr(target_message)); } template void ClearMessage(hpb::internal::PtrOrRaw message) { backend::ClearMessage(message); } template ABSL_MUST_USE_RESULT bool Parse(Ptr message, absl::string_view bytes) { static_assert(!std::is_const_v); 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 ABSL_MUST_USE_RESULT bool Parse( Ptr message, absl::string_view bytes, const ::hpb::ExtensionRegistry& extension_registry) { static_assert(!std::is_const_v); 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 ABSL_MUST_USE_RESULT bool Parse( T* message, absl::string_view bytes, const ::hpb::ExtensionRegistry& extension_registry) { static_assert(!std::is_const_v); return Parse(Ptr(message, bytes, extension_registry)); } template ABSL_MUST_USE_RESULT bool Parse(T* message, absl::string_view bytes) { static_assert(!std::is_const_v); 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 absl::StatusOr 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 absl::StatusOr 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 absl::StatusOr 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 absl::StatusOr Serialize(Ptr 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_