|  | // 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_UPB_H__ | 
|  | #define GOOGLE_PROTOBUF_HPB_BACKEND_UPB_UPB_H__ | 
|  |  | 
|  | #include <cstddef> | 
|  |  | 
|  | #include "absl/status/statusor.h" | 
|  | #include "absl/strings/string_view.h" | 
|  | #include "hpb/arena.h" | 
|  | #include "hpb/backend/upb/interop.h" | 
|  | #include "hpb/extension.h" | 
|  | #include "hpb/internal/internal.h" | 
|  | #include "hpb/internal/message_lock.h" | 
|  | #include "hpb/internal/template_help.h" | 
|  | #include "hpb/ptr.h" | 
|  | #include "hpb/status.h" | 
|  | #include "upb/mem/arena.h" | 
|  | #include "upb/message/message.h" | 
|  | #include "upb/wire/decode.h" | 
|  |  | 
|  | // Must be last. | 
|  | #include "upb/port/def.inc" | 
|  |  | 
|  | namespace hpb::internal::backend::upb { | 
|  |  | 
|  | template <size_t N> | 
|  | class DefaultInstance { | 
|  | public: | 
|  | static const upb_Message* msg() { return (upb_Message*)buffer_; } | 
|  | static upb_Arena* arena() { return arena_; } | 
|  |  | 
|  | private: | 
|  | alignas(UPB_MALLOC_ALIGN) static constexpr char buffer_[N] = {0}; | 
|  | static inline upb_Arena* arena_ = upb_Arena_New(); | 
|  | }; | 
|  |  | 
|  | template <typename T> | 
|  | typename T::Proxy CreateMessage(hpb::Arena& arena) { | 
|  | return PrivateAccess::CreateMessage<T>(hpb::interop::upb::UnwrapArena(arena)); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | typename T::Proxy CloneMessage(Ptr<T> message, hpb::Arena& arena) { | 
|  | return internal::PrivateAccess::Proxy<T>( | 
|  | internal::DeepClone(interop::upb::GetMessage(message), T::minitable(), | 
|  | hpb::interop::upb::UnwrapArena(arena)), | 
|  | hpb::interop::upb::UnwrapArena(arena)); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | void ClearMessage(PtrOrRawMutable<T> message) { | 
|  | auto ptr = Ptr(message); | 
|  | auto minitable = interop::upb::GetMiniTable(ptr); | 
|  | upb_Message_Clear(interop::upb::GetMessage(ptr), minitable); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | void DeepCopy(Ptr<const T> source_message, Ptr<T> target_message) { | 
|  | static_assert(!std::is_const_v<T>); | 
|  | internal::DeepCopy(interop::upb::GetMessage(target_message), | 
|  | interop::upb::GetMessage(source_message), T::minitable(), | 
|  | interop::upb::GetArena(target_message)); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | absl::StatusOr<absl::string_view> Serialize(PtrOrRaw<T> message, | 
|  | hpb::Arena& arena) { | 
|  | return hpb::internal::Serialize(interop::upb::GetMessage(message), | 
|  | interop::upb::GetMiniTable(message), | 
|  | hpb::interop::upb::UnwrapArena(arena), 0); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | bool Parse(PtrOrRaw<T> message, absl::string_view bytes, | 
|  | const ExtensionRegistry& extension_registry) { | 
|  | static_assert(!std::is_const_v<T>); | 
|  | upb_Message_Clear(interop::upb::GetMessage(message), | 
|  | interop::upb::GetMiniTable(message)); | 
|  | auto* arena = interop::upb::GetArena(message); | 
|  | return upb_Decode(bytes.data(), bytes.size(), | 
|  | interop::upb::GetMessage(message), | 
|  | interop::upb::GetMiniTable(message), | 
|  | internal::GetUpbExtensions(extension_registry), | 
|  | /* options= */ 0, arena) == kUpb_DecodeStatus_Ok; | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | absl::StatusOr<T> Parse(absl::string_view bytes, | 
|  | const ExtensionRegistry& extension_registry) { | 
|  | T message; | 
|  | auto* arena = interop::upb::GetArena(&message); | 
|  | upb_DecodeStatus status = | 
|  | upb_Decode(bytes.data(), bytes.size(), interop::upb::GetMessage(&message), | 
|  | interop::upb::GetMiniTable(&message), | 
|  | internal::GetUpbExtensions(extension_registry), | 
|  | /* options= */ 0, arena); | 
|  | if (status == kUpb_DecodeStatus_Ok) { | 
|  | return message; | 
|  | } | 
|  | return MessageDecodeError(status); | 
|  | } | 
|  |  | 
|  | }  // namespace hpb::internal::backend::upb | 
|  |  | 
|  | #include "upb/port/undef.inc" | 
|  |  | 
|  | #endif  // GOOGLE_PROTOBUF_HPB_BACKEND_UPB_UPB_H__ |