hpb: [multibackend] in this CL, we elide the generation of upb gencode if backend=cpp is detected. In that case, generator.cc will now generate a hpb(cpp) impl with message stubs.
Note that the old runtime's code (proto2::cpp) is not wrapped just yet.
PiperOrigin-RevId: 758164686
diff --git a/hpb/backend/cpp/cpp.h b/hpb/backend/cpp/cpp.h
index f92a15e..f4afcee 100644
--- a/hpb/backend/cpp/cpp.h
+++ b/hpb/backend/cpp/cpp.h
@@ -19,7 +19,7 @@
template <typename T>
typename T::Proxy CreateMessage(Arena& arena) {
- abort();
+ return typename T::Proxy();
}
template <typename T>
diff --git a/hpb/hpb.h b/hpb/hpb.h
index 89f2849..dcf8fe0 100644
--- a/hpb/hpb.h
+++ b/hpb/hpb.h
@@ -14,20 +14,19 @@
#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/wire/decode.h"
#define HPB_INTERNAL_BACKEND_UPB 1
#define HPB_INTERNAL_BACKEND_CPP 2
#if HPB_INTERNAL_BACKEND == HPB_INTERNAL_BACKEND_UPB
+#include "google/protobuf/hpb/backend/upb/interop.h"
#include "google/protobuf/hpb/backend/upb/upb.h"
+#include "upb/wire/decode.h"
+
#elif HPB_INTERNAL_BACKEND == HPB_INTERNAL_BACKEND_CPP
#include "google/protobuf/hpb/backend/cpp/cpp.h"
#else
diff --git a/hpb_generator/generator.cc b/hpb_generator/generator.cc
index fb8fa39..8347b4c 100644
--- a/hpb_generator/generator.cc
+++ b/hpb_generator/generator.cc
@@ -12,6 +12,8 @@
#include <utility>
#include <vector>
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_replace.h"
#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/compiler/code_generator_lite.h"
#include "google/protobuf/compiler/hpb/context.h"
@@ -52,7 +54,37 @@
void WriteHeader(const protobuf::FileDescriptor* file, Context& ctx) {
if (ctx.options().backend == Backend::CPP) {
- abort();
+ EmitFileWarning(file, ctx);
+ const auto msgs = SortedMessages(file);
+ for (auto message : msgs) {
+ ctx.Emit({{"type", QualifiedClassName(message)},
+ {"class_name", ClassName(message)},
+ {"namespace", absl::StrCat(absl::StrReplaceAll(file->package(),
+ {{".", "::"}}),
+ "::protos")}},
+ R"cc(
+ // message stubs
+ namespace $namespace$ {
+
+ class $class_name$ {
+ public:
+ using CProxy = bool;
+ using Proxy = bool;
+ using Access = bool;
+
+ $class_name$() = default;
+
+ $type$* msg() const { return msg_; }
+
+ private:
+ $class_name$($type$* msg) : msg_(msg) {}
+
+ $type$* msg_;
+ };
+ } // namespace $namespace$
+ )cc");
+ }
+ return;
}
EmitFileWarning(file, ctx);
ctx.EmitLegacy(
@@ -120,7 +152,8 @@
// Writes a .hpb.cc source file.
void WriteSource(const protobuf::FileDescriptor* file, Context& ctx) {
if (ctx.options().backend == Backend::CPP) {
- abort();
+ ctx.Emit("// Placeholder hpb C++ source stub");
+ return;
}
EmitFileWarning(file, ctx);
diff --git a/hpb_generator/tests/multibackend_test.cc b/hpb_generator/tests/multibackend_test.cc
new file mode 100644
index 0000000..c69f338
--- /dev/null
+++ b/hpb_generator/tests/multibackend_test.cc
@@ -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
+
+#include <gtest/gtest.h>
+#include "google/protobuf/compiler/hpb/tests/test_model.hpb.h"
+#include "google/protobuf/hpb/arena.h"
+#include "google/protobuf/hpb/hpb.h"
+
+namespace {
+using ::hpb_unittest::protos::TestModel;
+
+TEST(MultiBackend, CreateMessage) {
+ hpb::Arena arena;
+ auto msg = hpb::CreateMessage<TestModel>(arena);
+ (void)msg;
+}
+} // namespace