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