diff --git a/hpb/BUILD b/hpb/BUILD index 98a6761914..ad97ba8562 100644 --- a/hpb/BUILD +++ b/hpb/BUILD @@ -95,6 +95,7 @@ cc_library( "@abseil-cpp//absl/strings", ] + select({ ":hpb_backend_cpp": [ + "//hpb/backend/cpp:repeated_field", ], ":hpb_backend_upb": [ "//hpb/backend/upb:repeated_field", diff --git a/hpb/backend/BUILD b/hpb/backend/BUILD index b05ba2f061..fc615dd4dc 100644 --- a/hpb/backend/BUILD +++ b/hpb/backend/BUILD @@ -17,6 +17,7 @@ cc_library( "//hpb:multibackend", ] + select({ "//hpb:hpb_backend_cpp": [ + "//hpb/backend/cpp:error", "//src/google/protobuf:arena", ], "//hpb:hpb_backend_upb": [ diff --git a/hpb/backend/cpp/BUILD b/hpb/backend/cpp/BUILD index 1bee930040..35a94e6116 100644 --- a/hpb/backend/cpp/BUILD +++ b/hpb/backend/cpp/BUILD @@ -5,6 +5,7 @@ # license that can be found in the LICENSE file or at # https://developers.google.com/open-source/licenses/bsd +load("@rules_cc//cc:cc_test.bzl", "cc_test") load("@rules_cc//cc:defs.bzl", "cc_library") package(default_applicable_licenses = ["//:license"]) @@ -30,3 +31,28 @@ cc_library( "//hpb/internal", ], ) + +cc_library( + name = "error", + hdrs = ["error.h"], + visibility = ["//hpb:__subpackages__"], +) + +cc_library( + name = "repeated_field", + hdrs = ["repeated_field.h"], + visibility = ["//hpb:__subpackages__"], +) + +cc_test( + name = "cpp_test", + srcs = ["cpp_test.cc"], + deps = [ + "//hpb", + "//hpb:arena", + "//hpb:ptr", + "//hpb_generator/tests:test_model_hpb_proto", + "@googletest//:gtest", + "@googletest//:gtest_main", + ], +) diff --git a/hpb/backend/cpp/cpp.h b/hpb/backend/cpp/cpp.h index e7288c8bf1..58ea8f466f 100644 --- a/hpb/backend/cpp/cpp.h +++ b/hpb/backend/cpp/cpp.h @@ -20,12 +20,12 @@ namespace hpb::internal::backend::cpp { // hpb(cpp) backend stubs. template -typename T::Proxy CreateMessage(Arena& arena) { +typename T::Proxy CreateMessage(hpb::Arena& arena) { return typename T::Proxy(); } template -typename T::Proxy CloneMessage(Ptr message, Arena& arena) { +typename T::Proxy CloneMessage(Ptr message, hpb::Arena& arena) { abort(); } @@ -40,7 +40,7 @@ void DeepCopy(Ptr source_message, Ptr target_message) { } template -absl::string_view Serialize(PtrOrRaw message, Arena& arena) { +absl::string_view Serialize(PtrOrRaw message, hpb::Arena& arena) { abort(); } diff --git a/hpb/backend/cpp/cpp_test.cc b/hpb/backend/cpp/cpp_test.cc new file mode 100644 index 0000000000..6500249cd8 --- /dev/null +++ b/hpb/backend/cpp/cpp_test.cc @@ -0,0 +1,25 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2025 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 + +#include +#include "hpb_generator/tests/test_model.hpb.h" +#include "hpb/arena.h" +#include "hpb/hpb.h" +#include "hpb/ptr.h" + +namespace hpb::testing { +namespace { + +using ::hpb_unittest::protos::TestModel; + +TEST(CppBackend, CanCreateMessage) { + hpb::Arena arena; + hpb::Ptr test_model_ptr = hpb::CreateMessage(arena); + (void)test_model_ptr; +} +} // namespace +} // namespace hpb::testing diff --git a/hpb/backend/cpp/error.h b/hpb/backend/cpp/error.h new file mode 100644 index 0000000000..2475ae2750 --- /dev/null +++ b/hpb/backend/cpp/error.h @@ -0,0 +1,21 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2025 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_CPP_ERROR_H__ +#define GOOGLE_PROTOBUF_HPB_BACKEND_CPP_ERROR_H__ + +namespace hpb { +namespace internal { +namespace backend { +namespace cpp { +class Error {}; +} // namespace cpp +} // namespace backend +} // namespace internal +} // namespace hpb + +#endif // GOOGLE_PROTOBUF_HPB_BACKEND_CPP_ERROR_H__ diff --git a/hpb/backend/cpp/repeated_field.h b/hpb/backend/cpp/repeated_field.h new file mode 100644 index 0000000000..d76e4fbef4 --- /dev/null +++ b/hpb/backend/cpp/repeated_field.h @@ -0,0 +1,24 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2025 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_CPP_REPEATED_FIELD_H__ +#define GOOGLE_PROTOBUF_HPB_BACKEND_CPP_REPEATED_FIELD_H__ + +namespace hpb::internal { + +template +class RepeatedFieldScalarProxy {}; + +template +class RepeatedFieldStringProxy {}; + +template +class RepeatedFieldProxy {}; + +} // namespace hpb::internal + +#endif // GOOGLE_PROTOBUF_HPB_BACKEND_CPP_REPEATED_FIELD_H__ diff --git a/hpb/backend/types.h b/hpb/backend/types.h index f1b023e4a0..1bae6a8883 100644 --- a/hpb/backend/types.h +++ b/hpb/backend/types.h @@ -14,6 +14,7 @@ #include "upb/mem/arena.hpp" #elif HPB_INTERNAL_BACKEND == HPB_INTERNAL_BACKEND_CPP #include "google/protobuf/arena.h" +#include "hpb/backend/cpp/error.h" #endif namespace hpb { @@ -25,6 +26,7 @@ namespace upb { using Arena = ::upb::Arena; } #elif HPB_INTERNAL_BACKEND == HPB_INTERNAL_BACKEND_CPP +using Error = ::hpb::internal::backend::cpp::Error; namespace cpp { using Arena = google::protobuf::Arena; } diff --git a/hpb/extension.cc b/hpb/extension.cc index da3d4a9f54..d0270f3893 100644 --- a/hpb/extension.cc +++ b/hpb/extension.cc @@ -7,6 +7,9 @@ #include "hpb/extension.h" +#include "hpb/multibackend.h" + +#if HPB_INTERNAL_BACKEND == HPB_INTERNAL_BACKEND_UPB #include "upb/mini_table/extension_registry.h" namespace hpb { @@ -15,6 +18,6 @@ upb_ExtensionRegistry* GetUpbExtensions( const ExtensionRegistry& extension_registry) { return extension_registry.registry_; } - } // namespace internal } // namespace hpb +#endif diff --git a/hpb/hpb.h b/hpb/hpb.h index 5171810e89..c79f6252e3 100644 --- a/hpb/hpb.h +++ b/hpb/hpb.h @@ -64,6 +64,13 @@ void ClearMessage(internal::PtrOrRawMutable message) { backend::ClearMessage(message); } +// Note that the default extension registry is the the generated registry. +template +hpb::StatusOr Parse(absl::string_view bytes, ParseOptions options) { + return backend::Parse(bytes, options); +} + +#if HPB_INTERNAL_BACKEND == HPB_INTERNAL_BACKEND_UPB template ABSL_MUST_USE_RESULT bool Parse(internal::PtrOrRaw message, absl::string_view bytes, @@ -72,11 +79,6 @@ ABSL_MUST_USE_RESULT bool Parse(internal::PtrOrRaw message, return backend::Parse(message, bytes, extension_registry); } -// Note that the default extension registry is the the generated registry. -template -hpb::StatusOr Parse(absl::string_view bytes, ParseOptions options) { - return backend::Parse(bytes, options); -} // Deprecated. Use the overload that returns hpb::StatusOr instead. // Note that the default extension registry is the empty registry. @@ -87,6 +89,7 @@ absl::StatusOr Parse(absl::string_view bytes, ExtensionRegistry::empty_registry()) { return backend::Parse(bytes, extension_registry); } +#endif template absl::StatusOr Serialize(internal::PtrOrRaw message, diff --git a/hpb/repeated_field.h b/hpb/repeated_field.h index b452bf8e03..de67268b8d 100644 --- a/hpb/repeated_field.h +++ b/hpb/repeated_field.h @@ -18,6 +18,10 @@ #if HPB_INTERNAL_BACKEND == HPB_INTERNAL_BACKEND_UPB #include "hpb/backend/upb/repeated_field.h" +#elif HPB_INTERNAL_BACKEND == HPB_INTERNAL_BACKEND_CPP +#include "hpb/backend/cpp/repeated_field.h" +#else +#error "Unsupported backend" #endif namespace hpb { diff --git a/hpb_generator/generator.cc b/hpb_generator/generator.cc index bd7507136d..f534ade711 100644 --- a/hpb_generator/generator.cc +++ b/hpb_generator/generator.cc @@ -65,6 +65,8 @@ void WriteHeader(const google::protobuf::FileDescriptor* file, Context& ctx) { {{".", "::"}}), "::protos")}}, R"cc( +#include "hpb/internal/internal.h" + // message stubs namespace $namespace$ {