diff --git a/MODULE.bazel b/MODULE.bazel
index 04a8b56dc1..8848636379 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -24,7 +24,7 @@ bazel_dep(name = "rules_proto", version = "7.1.0")
#endif // PROTO2_OPENSOURCE
# protoc dependencies
bazel_dep(name = "abseil-cpp", version = "20250512.1")
-bazel_dep(name = "rules_cc", version = "0.0.17")
+bazel_dep(name = "rules_cc", version = "0.2.18")
bazel_dep(name = "zlib", version = "1.3.1.bcr.5")
#ifndef PROTO2_OPENSOURCE
# LINT.ThenChange(//depot/google3/third_party/protobuf/compiler/notices.h)
diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec
index 02e3a62dea..2cb5ec03ff 100644
--- a/csharp/Google.Protobuf.Tools.nuspec
+++ b/csharp/Google.Protobuf.Tools.nuspec
@@ -23,8 +23,8 @@
@@ -37,9 +37,11 @@
+
diff --git a/csharp/generate_protos.sh b/csharp/generate_protos.sh
index 6f9dbd5d19..3b73aeb949 100755
--- a/csharp/generate_protos.sh
+++ b/csharp/generate_protos.sh
@@ -67,6 +67,7 @@ $PROTOC -Isrc -I. -Ijava/core/src/main/resources/ \
conformance/test_protos/test_messages_edition2023.proto \
conformance/test_protos/test_messages_edition_unstable.proto \
csharp/protos/map_unittest_proto3.proto \
+ csharp/protos/nrt.proto \
csharp/protos/unittest_issues.proto \
csharp/protos/unittest_custom_options_proto3.proto \
csharp/protos/unittest_proto3.proto \
diff --git a/csharp/google/protobuf/c_sharp_features.proto b/csharp/google/protobuf/c_sharp_features.proto
index eb9af73b2e..f26300f168 100644
--- a/csharp/google/protobuf/c_sharp_features.proto
+++ b/csharp/google/protobuf/c_sharp_features.proto
@@ -20,4 +20,17 @@ extend google.protobuf.FeatureSet {
}
message CSharpFeatures {
+ // Whether the generated files should have nullable reference type annotations.
+ // When enabled, the generated C# code includes `#nullable enable annotations`
+ // and annotates message-typed properties and certain parameters with `?`.
+ optional bool nullable_reference_types = 1 [
+ retention = RETENTION_RUNTIME,
+ targets = TARGET_TYPE_FIELD,
+ targets = TARGET_TYPE_MESSAGE,
+ targets = TARGET_TYPE_FILE,
+ feature_support = {
+ edition_introduced: EDITION_UNSTABLE,
+ },
+ edition_defaults = { edition: EDITION_LEGACY, value: "false" }
+ ];
}
diff --git a/csharp/protos/nrt.proto b/csharp/protos/nrt.proto
new file mode 100644
index 0000000000..00b7f22978
--- /dev/null
+++ b/csharp/protos/nrt.proto
@@ -0,0 +1,55 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2026 Google Inc. 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
+
+edition = "UNSTABLE";
+
+package protobuf_editionstesting;
+
+import "csharp/protos/unittest_import_proto3.proto";
+import "csharp/protos/unittest.proto";
+
+import option "csharp/google/protobuf/c_sharp_features.proto";
+option features.(pb.csharp).nullable_reference_types = true;
+option csharp_namespace = "Google.Protobuf.TestProtos";
+
+// This file is used for testing NRT support in C#, both in terms of
+// manual inspection of the generated code, and checking that it compiles.
+// It exercises many aspects of protobuf, but does not attempt to be
+// comprehensive in checking (for example) all primitive numeric types.
+
+extend protobuf_unittest_proto2.TestAllExtensions {
+ int32 int32_ext = 1234567;
+ string string_ext = 1234568;
+ protobuf_unittest_proto2.TestAllExtensions message_ext = 1234569;
+}
+
+message NrtMessage {
+ protobuf_unittest_import.ImportMessage proto3_import_message = 1;
+ OtherNrtMessage other_message = 2;
+ string text = 3;
+ int32 integer = 4;
+ bytes blob = 5;
+ NrtEnum enum_field = 6;
+
+ message NestedMessage {
+ string text = 1;
+ }
+}
+
+message OtherNrtMessage {
+ string text = 1;
+}
+
+message ExtendableNrtMessage {
+ extensions 65536 to max;
+}
+
+enum NrtEnum {
+ NRT_ENUM_UNSPECIFIED = 0;
+ FOO = 1;
+ BAR = 2;
+}
diff --git a/csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs b/csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs
index 388041fe9c..53f962d4e0 100644
--- a/csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs
+++ b/csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs
@@ -10,6 +10,7 @@
using NUnit.Framework;
using System.Diagnostics;
using System;
+using System.Linq;
using System.Reflection;
using System.IO;
@@ -43,11 +44,13 @@ namespace Google.Protobuf
// "XYZ is obsolete: 'Types with embedded references are not supported in this version of your compiler.'"
// We build the code with GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE to avoid the use of ref struct in the generated code.
var compatibilityFlag = "-define:GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE";
- var sources = "*.cs"; // the generated sources from the TestProtos project
+ var sources = Directory.GetFiles(testProtosProjectDir, "*.cs")
+ .Select(Path.GetFileName)
+ .Except(new[] { "Nrt.pb.cs" }); // We don't expect the NRT code to compile with the old compiler.
// We suppress CS1691, which flags a warning for the generated line of
// #pragma warning disable 1591, 0612, 3021, 8981
// because CS8981 is unknown to this version of the compiler.
- var args = $"-langversion:3 -nologo -nowarn:1691 -target:library {compatibilityFlag} -reference:netstandard.dll -reference:{testProtosOutputDir}\\Google.Protobuf.dll -out:{testProtosOutputDir}\\TestProtos.RefStructCompatibilityTest.OldCompiler.dll {sources}";
+ var args = $"-langversion:3 -nologo -nowarn:1691 -target:library {compatibilityFlag} -reference:netstandard.dll -reference:{testProtosOutputDir}\\Google.Protobuf.dll -out:{testProtosOutputDir}\\TestProtos.RefStructCompatibilityTest.OldCompiler.dll {string.Join(" ", sources)}";
RunOldCsharpCompilerAndCheckSuccess(args, testProtosProjectDir);
}
diff --git a/examples/MODULE.bazel b/examples/MODULE.bazel
index ab848dcd8c..464407cbe1 100644
--- a/examples/MODULE.bazel
+++ b/examples/MODULE.bazel
@@ -19,7 +19,7 @@ local_path_override(
)
bazel_dep(name = "bazel_skylib", version = "1.7.1")
-bazel_dep(name = "rules_cc", version = "0.0.17")
+bazel_dep(name = "rules_cc", version = "0.2.18")
bazel_dep(name = "rules_java", version = "8.6.1")
bazel_dep(name = "rules_pkg", version = "1.0.1")
bazel_dep(name = "rules_python", version = "1.6.0")
diff --git a/protobuf_deps.bzl b/protobuf_deps.bzl
index c590bc9eb0..72785fb58d 100644
--- a/protobuf_deps.bzl
+++ b/protobuf_deps.bzl
@@ -103,9 +103,9 @@ def protobuf_deps():
if not native.existing_rule("rules_cc"):
http_archive(
name = "rules_cc",
- urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.16/rules_cc-0.0.16.tar.gz"],
- sha256 = "bbf1ae2f83305b7053b11e4467d317a7ba3517a12cef608543c1b1c5bf48a4df",
- strip_prefix = "rules_cc-0.0.16",
+ urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.1.5/rules_cc-0.1.5.tar.gz"],
+ sha256 = "b8b918a85f9144c01f6cfe0f45e4f2838c7413961a8ff23bc0c6cdf8bb07a3b6",
+ strip_prefix = "rules_cc-0.1.5",
)
if not native.existing_rule("rules_java"):
diff --git a/src/google/protobuf/compiler/csharp/BUILD.bazel b/src/google/protobuf/compiler/csharp/BUILD.bazel
index 61d9587944..55c8350e3f 100644
--- a/src/google/protobuf/compiler/csharp/BUILD.bazel
+++ b/src/google/protobuf/compiler/csharp/BUILD.bazel
@@ -80,6 +80,7 @@ cc_library(
"//src/google/protobuf/compiler:__pkg__",
],
deps = [
+ ":csharp_features_bootstrap",
":names",
"//src/google/protobuf",
"//src/google/protobuf:port",
@@ -137,6 +138,22 @@ cc_test(
],
)
+cc_library(
+ name = "csharp_features_bootstrap",
+ srcs = ["c_sharp_features.pb.cc"],
+ hdrs = ["c_sharp_features.pb.h"],
+ copts = COPTS,
+ strip_include_prefix = "/src",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//src/google/protobuf",
+ "//src/google/protobuf:arena",
+ "//src/google/protobuf:port",
+ "//src/google/protobuf:protobuf_lite",
+ "//src/google/protobuf/io",
+ ],
+)
+
################################################################################
# Distribution packaging
################################################################################
diff --git a/src/google/protobuf/compiler/csharp/c_sharp_features.pb.cc b/src/google/protobuf/compiler/csharp/c_sharp_features.pb.cc
new file mode 100755
index 0000000000..72ec5eaf7f
--- /dev/null
+++ b/src/google/protobuf/compiler/csharp/c_sharp_features.pb.cc
@@ -0,0 +1,430 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// NO CHECKED-IN PROTOBUF GENCODE
+// source: google/protobuf/compiler/csharp/c_sharp_features.proto
+// Protobuf C++ Version: 7.36.0-dev
+
+#include "google/protobuf/compiler/csharp/c_sharp_features.pb.h"
+
+#include
+#include
+#include "google/protobuf/io/coded_stream.h"
+#include "google/protobuf/generated_message_tctable_impl.h"
+#include "google/protobuf/internal_visibility.h"
+#include "google/protobuf/extension_set.h"
+#include "google/protobuf/generated_message_util.h"
+#include "google/protobuf/wire_format_lite.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/generated_message_reflection.h"
+#include "google/protobuf/reflection_ops.h"
+#include "google/protobuf/wire_format.h"
+// @@protoc_insertion_point(includes)
+
+// Must be included last.
+#include "google/protobuf/port_def.inc"
+PROTOBUF_PRAGMA_INIT_SEG
+namespace _pb = ::google::protobuf;
+namespace _pbi = ::google::protobuf::internal;
+namespace _fl = ::google::protobuf::internal::field_layout;
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+namespace {
+PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData
+ file_reflection_data[] = {
+ // ::pb::CSharpFeatures
+ {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto, /* tracker*/ nullptr,},
+};
+} // namespace
+#endif
+namespace pb {
+class CSharpFeatures::_Internal {
+ public:
+ using HasBits = decltype(::std::declval()._impl_._has_bits_);
+ static constexpr ::int32_t kHasBitsOffset =
+ 8 * PROTOBUF_FIELD_OFFSET(CSharpFeatures, _impl_._has_bits_);
+};
+
+constexpr CSharpFeatures::ParseTableT_ CSharpFeatures::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) {
+ return ParseTableT_{
+ {
+ PROTOBUF_FIELD_OFFSET(CSharpFeatures, _impl_._has_bits_),
+ 0, // no _extensions_
+ 1, 0, // max_field_number, fast_idx_mask
+ offsetof(ParseTableT_, field_lookup_table),
+ 4294967294, // skipmap
+ offsetof(ParseTableT_, field_entries),
+ 1, // num_field_entries
+ 0, // num_aux_entries
+ offsetof(ParseTableT_, field_names), // no aux_entries
+ class_data,
+ nullptr, // post_loop_handler
+ ::_pbi::TcParser::GenericFallback, // fallback
+ #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
+ ::_pbi::TcParser::GetTable<::pb::CSharpFeatures>(), // to_prefetch
+ #endif // PROTOBUF_PREFETCH_PARSE_TABLE
+ }, {{
+ // optional bool nullable_reference_types = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_FILE, edition_defaults = {
+ {::_pbi::TcParser::SingularVarintNoZag1(),
+ {8, 0, 0,
+ PROTOBUF_FIELD_OFFSET(CSharpFeatures, _impl_.nullable_reference_types_)}},
+ }}, {{
+ 65535, 65535
+ }}, {{
+ // optional bool nullable_reference_types = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_FILE, edition_defaults = {
+ {PROTOBUF_FIELD_OFFSET(CSharpFeatures, _impl_.nullable_reference_types_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)},
+ }},
+ // no aux_entries
+ {{
+ }},
+ };
+}
+
+
+inline constexpr CSharpFeatures::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ ::_pbi::ConstantInitialized) noexcept
+ : nullable_reference_types_{false} {}
+
+template
+constexpr CSharpFeatures::CSharpFeatures(::_pbi::ConstantInitialized,
+ const ::_pbi::ClassData* PROTOBUF_NONNULL class_data)
+ : Super_(
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ class_data
+#endif // PROTOBUF_CUSTOM_VTABLE
+ ),
+ _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) {
+}
+inline void* PROTOBUF_NONNULL CSharpFeatures::PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {
+ return ::new (mem) CSharpFeatures(arena);
+}
+constexpr auto CSharpFeatures::InternalNewImpl_() {
+ return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(CSharpFeatures), alignof(CSharpFeatures));
+}
+constexpr auto CSharpFeatures::InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* tc_table) {
+ return ::google::protobuf::internal::ClassDataFull{
+ ::google::protobuf::internal::ClassData{
+ &prototype,
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ &_table_.header,
+#else
+ tc_table,
+#endif
+ nullptr, // IsInitialized
+ &CSharpFeatures::MergeImpl,
+ Super_::GetNewImpl(),
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ &CSharpFeatures::SharedDtor,
+ Super_::GetClearImpl(), &CSharpFeatures::ByteSizeLong,
+ &CSharpFeatures::_InternalSerialize,
+#endif // PROTOBUF_CUSTOM_VTABLE
+ PROTOBUF_FIELD_OFFSET(CSharpFeatures, _impl_._cached_size_),
+ false,
+ },
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ &file_reflection_data[0],
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ &::_pbi::kDescriptorMethods,
+ &descriptor_table_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto,
+ nullptr, // tracker
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ };
+}
+struct CSharpFeaturesGlobalsTypeInternal : ::_pbi::MessageGlobalsBase {
+ constexpr CSharpFeaturesGlobalsTypeInternal()
+ :
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+ _default(::_pbi::ConstantInitialized{},
+ CSharpFeatures_class_data_.base())
+#else // !PROTOBUF_MESSAGE_GLOBALS
+ MessageGlobalsBase(CSharpFeatures::InternalGenerateClassData_(
+ _default, &CSharpFeatures_globals_._table.header)),
+ _default(::_pbi::ConstantInitialized{}, GetClassData()),
+ _table(::_pbi::PrivateAccess::GenerateParseTable(
+ GetClassData()))
+#endif // PROTOBUF_MESSAGE_GLOBALS
+ {
+ }
+ ~CSharpFeaturesGlobalsTypeInternal() {}
+ union {
+ alignas(::_pbi::kMaxMessageAlignment) CSharpFeatures _default;
+ };
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ decltype(::_pbi::PrivateAccess::GenerateParseTable(
+ ::std::declval())) _table;
+#endif
+};
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+static_assert(PROTOBUF_FIELD_OFFSET(CSharpFeaturesGlobalsTypeInternal, _default) ==
+ ::_pbi::MessageGlobalsBase::OffsetToDefault());
+#endif // PROTOBUF_MESSAGE_GLOBALS
+
+PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOC_EXPORT
+ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST CSharpFeaturesGlobalsTypeInternal CSharpFeatures_globals_
+ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro);
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+namespace {
+const ::_pbi::ClassData* CSharpFeatures_get_class_data() {
+#ifdef PROTOBUF_MESSAGE_GLOBALS
+ return CSharpFeatures_globals_.GetClassData();
+#else
+ return CSharpFeatures_class_data_.base();
+#endif // PROTOBUF_MESSAGE_GLOBALS
+}
+} // namespace
+#endif // PROTOBUF_CUSTOM_VTABLE
+} // namespace pb
+static constexpr const ::_pb::EnumDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE
+ file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto = nullptr;
+static constexpr const ::_pb::ServiceDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE
+ file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto = nullptr;
+const ::uint32_t
+ TableStruct_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE(
+ protodesc_cold) = {
+ 0x081, // bitmap
+ PROTOBUF_FIELD_OFFSET(::pb::CSharpFeatures, _impl_._has_bits_),
+ 4, // hasbit index offset
+ PROTOBUF_FIELD_OFFSET(::pb::CSharpFeatures, _impl_.nullable_reference_types_),
+ 0,
+};
+
+static const ::_pbi::MigrationSchema
+ schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
+ {0, sizeof(::pb::CSharpFeatures)},
+};
+static const ::_pbi::MessageGlobalsBase* PROTOBUF_NONNULL const
+ file_message_globals[] = {
+ &::pb::CSharpFeatures_globals_,
+};
+const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE(
+ protodesc_cold) = {
+ "\n6google/protobuf/compiler/csharp/c_shar"
+ "p_features.proto\022\002pb\032 google/protobuf/de"
+ "scriptor.proto\"S\n\016CSharpFeatures\022A\n\030null"
+ "able_reference_types\030\001 \001(\010B\037\210\001\001\230\001\004\230\001\003\230\001\001"
+ "\242\001\n\022\005false\030\204\007\262\001\003\010\217N:@\n\006csharp\022\033.google.p"
+ "rotobuf.FeatureSet\030\354\007 \001(\0132\022.pb.CSharpFea"
+ "turesB9B\030CSharpFeaturesOuterClassP\001\252\002\032Go"
+ "ogle.Protobuf.Reflection"
+};
+static const ::_pbi::DescriptorTable* PROTOBUF_NONNULL const
+ descriptor_table_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto_deps[1] = {
+ &::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto,
+};
+static ::absl::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto_once;
+PROTOBUF_CONSTINIT const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto = {
+ false,
+ false,
+ 304,
+ descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto,
+ "google/protobuf/compiler/csharp/c_sharp_features.proto",
+ &descriptor_table_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto_once,
+ descriptor_table_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto_deps,
+ 1,
+ 1,
+ schemas,
+ file_message_globals,
+ TableStruct_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto::offsets,
+ file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto,
+ file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto,
+};
+namespace pb {
+// ===================================================================
+
+CSharpFeatures::CSharpFeatures(::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, CSharpFeatures_get_class_data()) {
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena) {
+#endif // PROTOBUF_CUSTOM_VTABLE
+ SharedCtor(arena);
+ // @@protoc_insertion_point(arena_constructor:pb.CSharpFeatures)
+}
+CSharpFeatures::CSharpFeatures(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const CSharpFeatures& from)
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ : Super_(arena, CSharpFeatures_get_class_data()),
+#else // PROTOBUF_CUSTOM_VTABLE
+ : Super_(arena),
+#endif // PROTOBUF_CUSTOM_VTABLE
+ _impl_(from._impl_) {
+ _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+}
+PROTOBUF_NDEBUG_INLINE CSharpFeatures::Impl_::Impl_(
+ [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
+ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
+ {}
+
+inline void CSharpFeatures::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) {
+ new (&_impl_) Impl_(internal_visibility(), arena);
+ _impl_.nullable_reference_types_ = {};
+}
+CSharpFeatures::~CSharpFeatures() {
+ // @@protoc_insertion_point(destructor:pb.CSharpFeatures)
+ SharedDtor(*this);
+}
+inline void CSharpFeatures::SharedDtor(MessageLite& self) {
+ CSharpFeatures& this_ = static_cast(self);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
+ ABSL_DCHECK(this_.GetArena() == nullptr);
+ this_._impl_.~Impl_();
+}
+
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const
+ ::google::protobuf::internal::ClassDataFull CSharpFeatures_class_data_ =
+ CSharpFeatures::InternalGenerateClassData_(CSharpFeatures_globals_._default);
+
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+CSharpFeatures::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&CSharpFeatures_class_data_);
+ ::google::protobuf::internal::PrefetchToLocalCache(CSharpFeatures_class_data_.tc_table);
+ return CSharpFeatures_class_data_.base();
+}
+#else
+PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+CSharpFeatures::GetClassData() const {
+ ::google::protobuf::internal::PrefetchToLocalCache(&CSharpFeatures_globals_);
+ ::google::protobuf::internal::PrefetchToLocalCache(
+ ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&CSharpFeatures_globals_));
+ return CSharpFeatures_globals_.GetClassData();
+}
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_CONSTINIT
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CSharpFeatures::ParseTableT_
+ CSharpFeatures::_table_ =
+ CSharpFeatures::InternalGenerateParseTable_(CSharpFeatures_class_data_.base());
+#endif // !PROTOBUF_MESSAGE_GLOBALS
+PROTOBUF_NOINLINE void CSharpFeatures::Clear() {
+ // @@protoc_insertion_point(message_clear_start:pb.CSharpFeatures)
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ ::uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void)cached_has_bits;
+
+ _impl_.nullable_reference_types_ = false;
+ _impl_._has_bits_.Clear();
+ _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::uint8_t* PROTOBUF_NONNULL CSharpFeatures::_InternalSerialize(
+ const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) {
+ const CSharpFeatures& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::uint8_t* PROTOBUF_NONNULL CSharpFeatures::_InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ const CSharpFeatures& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ this_.CheckHasBitConsistency();
+ }
+ // @@protoc_insertion_point(serialize_to_array_start:pb.CSharpFeatures)
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ // optional bool nullable_reference_types = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_FILE, edition_defaults = {
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ target = stream->EnsureSpace(target);
+ target = ::_pbi::WireFormatLite::WriteBoolToArray(
+ 1, this_._internal_nullable_reference_types(), target);
+ }
+
+ if (ABSL_PREDICT_FALSE(this_._internal_metadata_.have_unknown_fields())) {
+ target =
+ ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
+ this_._internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:pb.CSharpFeatures)
+ return target;
+}
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+::size_t CSharpFeatures::ByteSizeLong(const MessageLite& base) {
+ const CSharpFeatures& this_ = static_cast(base);
+#else // PROTOBUF_CUSTOM_VTABLE
+::size_t CSharpFeatures::ByteSizeLong() const {
+ const CSharpFeatures& this_ = *this;
+#endif // PROTOBUF_CUSTOM_VTABLE
+ // @@protoc_insertion_point(message_byte_size_start:pb.CSharpFeatures)
+ ::size_t total_size = 0;
+
+ ::uint32_t cached_has_bits = 0;
+ // Prevent compiler warnings about cached_has_bits being unused
+ (void)cached_has_bits;
+
+ cached_has_bits = this_._impl_._has_bits_[0];
+ total_size += static_cast(0x00000001U & cached_has_bits) * 2;
+ return this_.MaybeComputeUnknownFieldsSize(total_size,
+ &this_._impl_._cached_size_);
+}
+
+void CSharpFeatures::MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg) {
+ auto* const _this = static_cast(&to_msg);
+ auto& from = static_cast(from_msg);
+ if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
+ from.CheckHasBitConsistency();
+ }
+ // @@protoc_insertion_point(class_specific_merge_from_start:pb.CSharpFeatures)
+ ABSL_DCHECK_NE(&from, _this);
+ ::uint32_t cached_has_bits = 0;
+ (void)cached_has_bits;
+
+ cached_has_bits = from._impl_._has_bits_[0];
+ if (CheckHasBit(cached_has_bits, 0x00000001U)) {
+ _this->_impl_.nullable_reference_types_ = from._impl_.nullable_reference_types_;
+ }
+ _this->_impl_._has_bits_[0] |= cached_has_bits;
+ _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
+ from._internal_metadata_);
+}
+
+void CSharpFeatures::CopyFrom(const CSharpFeatures& from) {
+ // @@protoc_insertion_point(class_specific_copy_from_start:pb.CSharpFeatures)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+
+void CSharpFeatures::InternalSwap(CSharpFeatures* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) {
+ using ::std::swap;
+ _internal_metadata_.InternalSwap(&other->_internal_metadata_);
+ swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
+ swap(_impl_.nullable_reference_types_, other->_impl_.nullable_reference_types_);
+}
+
+::google::protobuf::Metadata CSharpFeatures::GetMetadata() const {
+ return Super_::GetMetadataImpl(GetClassData()->full());
+}
+PROTOBUF_CONSTINIT PROTOC_EXPORT
+ PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::ExtensionIdentifier<
+ ::google::protobuf::FeatureSet, ::_pbi::MessageTypeTraits< ::pb::CSharpFeatures >, 11, false>
+ csharp(kCsharpFieldNumber, &::pb::CSharpFeatures_globals_);
+// @@protoc_insertion_point(namespace_scope)
+} // namespace pb
+namespace google {
+namespace protobuf {
+} // namespace protobuf
+} // namespace google
+// @@protoc_insertion_point(global_scope)
+PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::std::false_type
+ _static_init2_ [[maybe_unused]] =
+ (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto),
+ ::_pbi::ExtensionSet::RegisterMessageExtension(
+ &::google::protobuf::FeatureSet::default_instance(), 1004, 11,
+ false, false, &::pb::CSharpFeatures::default_instance(),
+ nullptr, ::_pbi::LazyAnnotation::kUndefined),
+ ::std::false_type{});
+#include "google/protobuf/port_undef.inc"
diff --git a/src/google/protobuf/compiler/csharp/c_sharp_features.pb.h b/src/google/protobuf/compiler/csharp/c_sharp_features.pb.h
new file mode 100755
index 0000000000..8a2d11a016
--- /dev/null
+++ b/src/google/protobuf/compiler/csharp/c_sharp_features.pb.h
@@ -0,0 +1,338 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// NO CHECKED-IN PROTOBUF GENCODE
+// source: google/protobuf/compiler/csharp/c_sharp_features.proto
+// Protobuf C++ Version: 7.36.0-dev
+
+#ifndef google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto_2epb_2eh
+#define google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto_2epb_2eh
+
+#include
+#include
+#include
+#include
+
+// clang-format off
+#include "google/protobuf/runtime_version.h"
+#if PROTOBUF_VERSION != 7036000
+#error "Protobuf C++ gencode is built with an incompatible version of"
+#error "Protobuf C++ headers/runtime. See"
+#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
+#endif
+#include "google/protobuf/io/coded_stream.h"
+#include "google/protobuf/arena.h"
+#include "google/protobuf/arenastring.h"
+#include "google/protobuf/generated_message_tctable_decl.h"
+#include "google/protobuf/generated_message_util.h"
+#include "google/protobuf/metadata_lite.h"
+#include "google/protobuf/generated_message_reflection.h"
+#include "google/protobuf/message.h"
+#include "google/protobuf/message_lite.h"
+#include "google/protobuf/repeated_field.h" // IWYU pragma: export
+#include "google/protobuf/extension_set.h" // IWYU pragma: export
+#include "google/protobuf/unknown_field_set.h"
+#include "google/protobuf/descriptor.pb.h"
+// @@protoc_insertion_point(includes)
+
+// Must be included last.
+#include "google/protobuf/port_def.inc"
+
+#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto PROTOC_EXPORT
+
+// Internal implementation detail -- do not use these members.
+struct PROTOC_EXPORT TableStruct_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto {
+ static const ::uint32_t offsets[];
+};
+extern "C" {
+PROTOC_EXPORT extern const ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto;
+} // extern "C"
+namespace pb {
+class CSharpFeatures;
+struct CSharpFeaturesGlobalsTypeInternal;
+#ifndef PROTOBUF_MESSAGE_GLOBALS
+PROTOC_EXPORT extern CSharpFeaturesGlobalsTypeInternal CSharpFeatures_globals_;
+PROTOC_EXPORT extern const ::google::protobuf::internal::ClassDataFull CSharpFeatures_class_data_;
+#else
+PROTOC_EXPORT extern const CSharpFeaturesGlobalsTypeInternal CSharpFeatures_globals_;
+#endif // PROTOBUF_MESSAGE_GLOBALS
+} // namespace pb
+namespace google {
+namespace protobuf {
+namespace internal {
+template <>
+inline ::absl::string_view GetFeatureSetDefaultsData<::pb::CSharpFeatures>() {
+ static constexpr char kDefaults[] = "CiEYhAciA+I+ACoXCAEQAhgCIAMoATACOAJAAUgB4j4CCAAKIRjnByID4j4AKhcIAhABGAEgAigBMAE4AkABSAHiPgIIAAohGOgHIg8IARABGAEgAigBMAHiPgAqCzgCQAFIAeI+AggACiEY6QciEwgBEAEYASACKAEwATgBQALiPgAqB0gB4j4CCAAKIRjqByIVCAEQARgBIAIoATABOANAAkgC4j4AKgXiPgIIAAohGI9OIhcIARABGAEgAigBMAE4A0ACSALiPgIIACoD4j4AIOYHKOoH";
+ return kDefaults;
+}
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+namespace pb {
+
+// ===================================================================
+
+
+// -------------------------------------------------------------------
+
+class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CSharpFeatures final : public ::google::protobuf::Message
+/* @@protoc_insertion_point(class_definition:pb.CSharpFeatures) */ {
+ using Super_ = ::google::protobuf::Message;
+
+ public:
+ inline CSharpFeatures() : CSharpFeatures(nullptr) {}
+ ~CSharpFeatures() PROTOBUF_FINAL;
+
+#if defined(PROTOBUF_CUSTOM_VTABLE)
+ void operator delete(CSharpFeatures* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) {
+ SharedDtor(*msg);
+ ::google::protobuf::internal::SizedDelete(msg, sizeof(CSharpFeatures));
+ }
+#endif
+
+ template
+ explicit constexpr CSharpFeatures(::google::protobuf::internal::ConstantInitialized,
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
+ class_data);
+
+ inline CSharpFeatures(const CSharpFeatures& from) : CSharpFeatures(nullptr, from) {}
+ inline CSharpFeatures(CSharpFeatures&& from) noexcept : CSharpFeatures(nullptr, ::std::move(from)) {}
+ inline CSharpFeatures& operator=(const CSharpFeatures& from) {
+ CopyFrom(from);
+ return *this;
+ }
+ inline CSharpFeatures& operator=(CSharpFeatures&& from) noexcept {
+ if (this == &from) return *this;
+ if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) {
+ InternalSwap(&from);
+ } else {
+ CopyFrom(from);
+ }
+ return *this;
+ }
+
+ [[nodiscard]] inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const
+ ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance);
+ }
+ [[nodiscard]] inline ::google::protobuf::UnknownFieldSet* PROTOBUF_NONNULL
+ mutable_unknown_fields() ABSL_ATTRIBUTE_LIFETIME_BOUND {
+ return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>();
+ }
+
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() {
+ return GetDescriptor();
+ }
+ [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL
+ GetDescriptor() {
+ return default_instance().GetMetadata().descriptor;
+ }
+ [[nodiscard]] static const ::google::protobuf::Reflection* PROTOBUF_NONNULL GetReflection() {
+ return default_instance().GetMetadata().reflection;
+ }
+ [[nodiscard]] static const CSharpFeatures& default_instance() {
+ return *::google::protobuf::internal::MessageGlobalsBase::ToDefaultInstance(&CSharpFeatures_globals_);
+ }
+ static constexpr int kIndexInFileMessages = 0;
+ friend void swap(CSharpFeatures& a, CSharpFeatures& b) { a.Swap(&b); }
+ inline void Swap(CSharpFeatures* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) {
+ InternalSwap(other);
+ } else {
+ ::google::protobuf::internal::GenericSwap(this, other);
+ }
+ }
+ void UnsafeArenaSwap(CSharpFeatures* PROTOBUF_NONNULL other) {
+ if (other == this) return;
+ ABSL_DCHECK(GetArena() == other->GetArena());
+ InternalSwap(other);
+ }
+
+ // implements Message ----------------------------------------------
+
+ [[nodiscard]] CSharpFeatures* PROTOBUF_NONNULL
+ New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const {
+ return Super_::DefaultConstruct(arena);
+ }
+ using Super_::CopyFrom;
+ void CopyFrom(const CSharpFeatures& from);
+ using Super_::MergeFrom;
+ void MergeFrom(const CSharpFeatures& from) { CSharpFeatures::MergeImpl(*this, from); }
+
+ private:
+ static void MergeImpl(::google::protobuf::MessageLite& to_msg,
+ const ::google::protobuf::MessageLite& from_msg);
+
+ public:
+ [[nodiscard]] bool IsInitialized() const {
+ return true;
+ }
+ ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
+ #if defined(PROTOBUF_CUSTOM_VTABLE)
+ private:
+ [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg);
+ [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream);
+
+ public:
+ [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); }
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
+ return _InternalSerialize(*this, target, stream);
+ }
+ #else // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] ::size_t ByteSizeLong() const final;
+ [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize(
+ ::uint8_t* PROTOBUF_NONNULL target,
+ ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final;
+ #endif // PROTOBUF_CUSTOM_VTABLE
+ [[nodiscard]] int GetCachedSize() const {
+ return _impl_._cached_size_.Get();
+ }
+
+ private:
+ void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static void SharedDtor(MessageLite& self);
+ void InternalSwap(CSharpFeatures* PROTOBUF_NONNULL other);
+ private:
+ static ::absl::string_view FullMessageName() { return "pb.CSharpFeatures"; }
+
+ explicit CSharpFeatures(::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ CSharpFeatures(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const CSharpFeatures& from);
+ CSharpFeatures(
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, CSharpFeatures&& from) noexcept
+ : CSharpFeatures(arena) {
+ *this = ::std::move(from);
+ }
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL;
+ static void* PROTOBUF_NONNULL PlacementNew_(
+ const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ static constexpr auto InternalNewImpl_();
+
+ public:
+ static constexpr auto InternalGenerateClassData_(
+ const MessageLite& prototype,
+ const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr);
+
+ [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const;
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+ enum : int {
+ kNullableReferenceTypesFieldNumber = 1,
+ };
+ // optional bool nullable_reference_types = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_FILE, edition_defaults = {
+ [[nodiscard]] bool has_nullable_reference_types() const;
+ void clear_nullable_reference_types() ;
+ [[nodiscard]] bool nullable_reference_types() const;
+ void set_nullable_reference_types(bool value);
+
+ private:
+ bool _internal_nullable_reference_types() const;
+ void _internal_set_nullable_reference_types(bool value);
+
+ public:
+ // @@protoc_insertion_point(class_scope:pb.CSharpFeatures)
+ private:
+ class _Internal;
+ using ParseTableT_ =
+ ::google::protobuf::internal::TcParseTable<0, 1,
+ 0, 0,
+ 2>;
+ static constexpr ParseTableT_ InternalGenerateParseTable_(
+ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data);
+ friend class ::google::protobuf::internal::TcParser;
+ #ifndef PROTOBUF_MESSAGE_GLOBALS
+ static const ParseTableT_ _table_;
+ #endif
+
+ friend class ::google::protobuf::MessageLite;
+ friend class ::google::protobuf::Arena;
+ friend ::google::protobuf::internal::PrivateAccess;
+ template
+ friend class ::google::protobuf::Arena::InternalHelper;
+ using InternalArenaConstructable_ = void;
+ using DestructorSkippable_ = void;
+ struct Impl_ {
+ inline explicit constexpr Impl_(::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::internal::ConstantInitialized) noexcept;
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena);
+ inline explicit Impl_(
+ ::google::protobuf::internal::InternalVisibility visibility,
+ ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from,
+ const CSharpFeatures& from_msg);
+ ::google::protobuf::internal::HasBits<1> _has_bits_;
+ ::google::protobuf::internal::CachedSize _cached_size_;
+ bool nullable_reference_types_;
+ PROTOBUF_TSAN_DECLARE_MEMBER
+ };
+ union { Impl_ _impl_; };
+ friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto;
+};
+
+// ===================================================================
+
+
+
+inline constexpr int kCsharpFieldNumber = 1004;
+PROTOC_EXPORT extern ::google::protobuf::internal::ExtensionIdentifier<
+ ::google::protobuf::FeatureSet, ::google::protobuf::internal::MessageTypeTraits< ::pb::CSharpFeatures >, 11, false>(csharp);
+
+// ===================================================================
+
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif // __GNUC__
+// -------------------------------------------------------------------
+
+// CSharpFeatures
+
+// optional bool nullable_reference_types = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_FILE, edition_defaults = {
+inline bool CSharpFeatures::has_nullable_reference_types() const {
+ bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000001U);
+ return value;
+}
+inline void CSharpFeatures::clear_nullable_reference_types() {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.nullable_reference_types_ = false;
+ ClearHasBit(_impl_._has_bits_[0], 0x00000001U);
+}
+inline bool CSharpFeatures::nullable_reference_types() const {
+ // @@protoc_insertion_point(field_get:pb.CSharpFeatures.nullable_reference_types)
+ return _internal_nullable_reference_types();
+}
+inline void CSharpFeatures::set_nullable_reference_types(bool value) {
+ _internal_set_nullable_reference_types(value);
+ SetHasBit(_impl_._has_bits_[0], 0x00000001U);
+ // @@protoc_insertion_point(field_set:pb.CSharpFeatures.nullable_reference_types)
+}
+inline bool CSharpFeatures::_internal_nullable_reference_types() const {
+ ::google::protobuf::internal::TSanRead(&_impl_);
+ return _impl_.nullable_reference_types_;
+}
+inline void CSharpFeatures::_internal_set_nullable_reference_types(bool value) {
+ ::google::protobuf::internal::TSanWrite(&_impl_);
+ _impl_.nullable_reference_types_ = value;
+}
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif // __GNUC__
+
+// @@protoc_insertion_point(namespace_scope)
+} // namespace pb
+
+
+// @@protoc_insertion_point(global_scope)
+
+#include "google/protobuf/port_undef.inc"
+// clang-format on
+
+#endif // google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto_2epb_2eh
diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc
index 290b38c71b..dd3b7a724c 100644
--- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc
@@ -14,6 +14,7 @@
#include "absl/log/absl_log.h"
#include "google/protobuf/compiler/code_generator.h"
+#include "google/protobuf/compiler/csharp/csharp_generator.h"
#include "google/protobuf/compiler/csharp/csharp_helpers.h"
#include "google/protobuf/compiler/csharp/names.h"
#include "google/protobuf/descriptor.h"
@@ -115,6 +116,9 @@ void FieldGeneratorBase::SetCommonFieldVariables(
absl::StrCat("other.", (*variables)["property_name"],
" != ", (*variables)["default_value"])});
}
+ // This isn't valid everywhere, but we assume that the code which uses
+ // the variable will only do so in a context where the annotation is valid.
+ (*variables)["nrt_annotation"] = nrt_enabled_ ? "?" : "";
}
void FieldGeneratorBase::SetCommonOneofFieldVariables(
@@ -129,6 +133,9 @@ void FieldGeneratorBase::SetCommonOneofFieldVariables(
}
(*variables)["oneof_case_name"] = oneof_case_name();
(*variables)["oneof_property_name"] = oneof_property_name();
+ // This isn't valid everywhere, but we assume that the code which uses
+ // the variable will only do so in a context where the annotation is valid.
+ (*variables)["nrt_annotation"] = nrt_enabled_ ? "?" : "";
}
FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor,
@@ -136,6 +143,9 @@ FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor,
: SourceGeneratorBase(options),
descriptor_(descriptor),
presenceIndex_(presenceIndex) {
+ nrt_enabled_ = Generator::GetResolvedSourceFeatures(*descriptor->file())
+ .GetExtension(pb::csharp)
+ .nullable_reference_types();
SetCommonFieldVariables(&variables_);
}
@@ -216,10 +226,12 @@ std::string FieldGeneratorBase::type_name(const FieldDescriptor* descriptor) {
const FieldDescriptor* wrapped_field =
descriptor->message_type()->field(0);
std::string wrapped_field_type_name = type_name(wrapped_field);
- // String and ByteString go to the same type; other wrapped types
- // go to the nullable equivalent.
- if (wrapped_field->type() == FieldDescriptor::TYPE_STRING ||
- wrapped_field->type() == FieldDescriptor::TYPE_BYTES) {
+ // String and ByteString go to the same type (unless nullable reference
+ // type is supported for this field); other wrapped types go to the
+ // nullable equivalent.
+ if (!nrt_enabled_ &&
+ (wrapped_field->type() == FieldDescriptor::TYPE_STRING ||
+ wrapped_field->type() == FieldDescriptor::TYPE_BYTES)) {
return wrapped_field_type_name;
} else {
return absl::StrCat(wrapped_field_type_name, "?");
diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h
index 39db3aa71e..c3347d7e8d 100644
--- a/src/google/protobuf/compiler/csharp/csharp_field_base.h
+++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h
@@ -55,6 +55,8 @@ class FieldGeneratorBase : public SourceGeneratorBase {
protected:
const FieldDescriptor* descriptor_;
const int presenceIndex_;
+ // NRT = Nullable Reference Types
+ bool nrt_enabled_;
absl::flat_hash_map variables_;
void AddDeprecatedFlag(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.h b/src/google/protobuf/compiler/csharp/csharp_generator.h
index 8fa15e5c06..84c7c1eac4 100644
--- a/src/google/protobuf/compiler/csharp/csharp_generator.h
+++ b/src/google/protobuf/compiler/csharp/csharp_generator.h
@@ -11,8 +11,10 @@
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_CSHARP_GENERATOR_H__
#include
+#include
#include "google/protobuf/compiler/code_generator.h"
+#include "google/protobuf/compiler/csharp/c_sharp_features.pb.h"
#include "google/protobuf/port_def.inc"
namespace google {
@@ -37,6 +39,11 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; }
Edition GetMaximumEdition() const override { return Edition::EDITION_2024; }
using CodeGenerator::GetEdition;
+
+ std::vector GetFeatureExtensions() const override {
+ return {GetExtensionReflection(pb::csharp)};
+ }
+ using CodeGenerator::GetResolvedSourceFeatures;
};
} // namespace csharp
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc
index d80b514207..8c2b0b4389 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message.cc
@@ -8,16 +8,15 @@
#include "google/protobuf/compiler/csharp/csharp_message.h"
#include
-#include
#include
#include "absl/container/flat_hash_map.h"
#include "absl/log/absl_log.h"
#include "absl/strings/str_cat.h"
-#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/compiler/csharp/csharp_doc_comment.h"
#include "google/protobuf/compiler/csharp/csharp_enum.h"
#include "google/protobuf/compiler/csharp/csharp_field_base.h"
+#include "google/protobuf/compiler/csharp/csharp_generator.h"
#include "google/protobuf/compiler/csharp/csharp_helpers.h"
#include "google/protobuf/compiler/csharp/csharp_options.h"
#include "google/protobuf/compiler/csharp/names.h"
@@ -60,6 +59,9 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor,
}
}
has_bit_field_count_ = (presence_bit_count + 31) / 32;
+ nrt_enabled_ = Generator::GetResolvedSourceFeatures(*descriptor->file())
+ .GetExtension(pb::csharp)
+ .nullable_reference_types();
}
MessageGenerator::~MessageGenerator() = default;
@@ -93,6 +95,7 @@ void MessageGenerator::Generate(io::Printer* printer) {
absl::flat_hash_map vars;
vars["class_name"] = class_name();
vars["access_level"] = class_access_level();
+ vars["nrt_annotation"] = nrt_enabled_ ? "?" : "";
WriteMessageDocComment(printer, options(), descriptor_);
AddDeprecatedFlag(printer);
@@ -120,23 +123,26 @@ void MessageGenerator::Generate(io::Printer* printer) {
"private static readonly pb::MessageParser<$class_name$> _parser = new "
"pb::MessageParser<$class_name$>(() => new $class_name$());\n");
- printer->Print("private pb::UnknownFieldSet _unknownFields;\n");
+ printer->Print(
+ vars, "private pb::UnknownFieldSet$nrt_annotation$ _unknownFields;\n");
if (has_extension_ranges_) {
if (IsDescriptorProto(descriptor_->file())) {
printer->Print(vars,
// CustomOptions compatibility
- "internal pb::ExtensionSet<$class_name$> _extensions;\n");
+ "internal pb::ExtensionSet<$class_name$>$nrt_annotation$ "
+ "_extensions;\n");
} else {
printer->Print(vars,
- "private pb::ExtensionSet<$class_name$> _extensions;\n");
+ "private pb::ExtensionSet<$class_name$>$nrt_annotation$ "
+ "_extensions;\n");
}
// a read-only property for fast
// retrieval of the set in IsInitialized
printer->Print(vars,
- "private pb::ExtensionSet<$class_name$> _Extensions { get { "
- "return _extensions; } }\n");
+ "private pb::ExtensionSet<$class_name$>$nrt_annotation$ "
+ " _Extensions { get { return _extensions; } }\n");
}
for (int i = 0; i < has_bit_field_count_; i++) {
@@ -256,7 +262,7 @@ void MessageGenerator::Generate(io::Printer* printer) {
"TValue> extension) {\n"
" return pb::ExtensionSet.Get(ref _extensions, extension);\n"
"}\n"
- "public pbc::RepeatedField "
+ "public pbc::RepeatedField$nrt_annotation$ "
"GetExtension(pb::RepeatedExtension<$class_name$, TValue> "
"extension) {\n"
" return pb::ExtensionSet.Get(ref _extensions, extension);\n"
@@ -417,16 +423,17 @@ void MessageGenerator::GenerateFreezingCode(io::Printer* printer) {}
void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) {
absl::flat_hash_map vars;
vars["class_name"] = class_name();
+ vars["nrt_annotation"] = nrt_enabled_ ? "?" : "";
// Equality
WriteGeneratedCodeAttributes(printer);
printer->Print(vars,
- "public override bool Equals(object other) {\n"
+ "public override bool Equals(object$nrt_annotation$ other) {\n"
" return Equals(other as $class_name$);\n"
"}\n\n");
WriteGeneratedCodeAttributes(printer);
printer->Print(vars,
- "public bool Equals($class_name$ other) {\n"
+ "public bool Equals($class_name$$nrt_annotation$ other) {\n"
" if (ReferenceEquals(other, null)) {\n"
" return false;\n"
" }\n"
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.h b/src/google/protobuf/compiler/csharp/csharp_message.h
index 96e47b3f3c..abaac580b6 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message.h
+++ b/src/google/protobuf/compiler/csharp/csharp_message.h
@@ -40,6 +40,8 @@ class MessageGenerator : public SourceGeneratorBase {
std::vector fields_by_number_;
int has_bit_field_count_;
bool has_extension_ranges_;
+ // NRT = Nullable Reference Types
+ bool nrt_enabled_;
void GenerateMessageSerializationMethods(io::Printer* printer);
void GenerateWriteToBody(io::Printer* printer, bool use_write_context);
diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc
index 0e6eee7d80..2c3f0932bc 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc
@@ -35,19 +35,17 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
MessageFieldGenerator::~MessageFieldGenerator() = default;
void MessageFieldGenerator::GenerateMembers(io::Printer* printer) {
- printer->Print(
- variables_,
- "private $type_name$ $name$_;\n");
+ printer->Print(variables_, "private $type_name$$nrt_annotation$ $name$_;\n");
WritePropertyDocComment(printer, options(), descriptor_);
AddPublicMemberAttributes(printer);
printer->Print(
- variables_,
- "$access_level$ $type_name$ $property_name$ {\n"
- " get { return $name$_; }\n"
- " set {\n"
- " $name$_ = value;\n"
- " }\n"
- "}\n");
+ variables_,
+ "$access_level$ $type_name$$nrt_annotation$ $property_name$ {\n"
+ " get { return $name$_; }\n"
+ " set {\n"
+ " $name$_ = value;\n"
+ " }\n"
+ "}\n");
if (SupportsPresenceApi(descriptor_)) {
printer->Print(
variables_,
@@ -189,14 +187,17 @@ void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
WritePropertyDocComment(printer, options(), descriptor_);
AddPublicMemberAttributes(printer);
printer->Print(
- variables_,
- "$access_level$ $type_name$ $property_name$ {\n"
- " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : null; }\n"
- " set {\n"
- " $oneof_name$_ = value;\n"
- " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$oneof_case_name$;\n"
- " }\n"
- "}\n");
+ variables_,
+ "$access_level$ $type_name$$nrt_annotation$ $property_name$ {\n"
+ " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : "
+ "null; }\n"
+ " set {\n"
+ " $oneof_name$_ = value;\n"
+ " $oneof_name$Case_ = value == null ? "
+ "$oneof_property_name$OneofCase.None : "
+ "$oneof_property_name$OneofCase.$oneof_case_name$;\n"
+ " }\n"
+ "}\n");
if (SupportsPresenceApi(descriptor_)) {
printer->Print(
variables_,
diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
index 1ed4c9f26a..58309d3145 100644
--- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
@@ -66,11 +66,15 @@ void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
std::string default_value = variables_["default_value"];
variables_["default_value_access"] = std::move(default_value);
}
+ // For string and bytes proto fields, the C# field is nullable, but the
+ // property isn't. (The null value is used for presence.)
+ variables_["nrt_field_annotation"] =
+ nrt_enabled_ && IsNullable(descriptor_) ? "?" : "";
// Declare the field itself.
printer->Print(
- variables_,
- "private $type_name$ $name_def_message$;\n");
+ variables_,
+ "private $type_name$$nrt_field_annotation$ $name_def_message$;\n");
WritePropertyDocComment(printer, options(), descriptor_);
AddPublicMemberAttributes(printer);
diff --git a/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc b/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc
index 2194dc5446..e1af11d240 100644
--- a/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc
@@ -13,10 +13,12 @@
#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/compiler/csharp/csharp_enum.h"
#include "google/protobuf/compiler/csharp/csharp_field_base.h"
+#include "google/protobuf/compiler/csharp/csharp_generator.h"
#include "google/protobuf/compiler/csharp/csharp_helpers.h"
#include "google/protobuf/compiler/csharp/csharp_message.h"
#include "google/protobuf/compiler/csharp/csharp_options.h"
#include "google/protobuf/compiler/csharp/names.h"
+#include "google/protobuf/compiler/csharp/c_sharp_features.pb.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/io/printer.h"
@@ -36,6 +38,9 @@ ReflectionClassGenerator::ReflectionClassGenerator(const FileDescriptor* file,
namespace_ = GetFileNamespace(file);
reflectionClassname_ = GetReflectionClassUnqualifiedName(file);
extensionClassname_ = GetExtensionClassUnqualifiedName(file);
+ nrt_enabled_ = Generator::GetResolvedSourceFeatures(*file)
+ .GetExtension(pb::csharp)
+ .nullable_reference_types();
}
ReflectionClassGenerator::~ReflectionClassGenerator() = default;
@@ -120,6 +125,10 @@ void ReflectionClassGenerator::WriteIntroduction(io::Printer* printer) {
printer->Print("\n");
}
+ if (nrt_enabled_) {
+ printer->Print("#nullable enable annotations\n");
+ }
+
printer->Print(
"/// Holder for reflection information generated from $file_name$\n"
"$access_level$ static partial class $reflection_class_name$ {\n"
diff --git a/src/google/protobuf/compiler/csharp/csharp_reflection_class.h b/src/google/protobuf/compiler/csharp/csharp_reflection_class.h
index af29bf82f9..306b66591f 100644
--- a/src/google/protobuf/compiler/csharp/csharp_reflection_class.h
+++ b/src/google/protobuf/compiler/csharp/csharp_reflection_class.h
@@ -36,6 +36,8 @@ class ReflectionClassGenerator : public SourceGeneratorBase {
std::string namespace_;
std::string reflectionClassname_;
std::string extensionClassname_;
+ // Whether or not nullable reference types are enabled for the whole file.
+ bool nrt_enabled_;
void WriteIntroduction(io::Printer* printer);
void WriteDescriptor(io::Printer* printer);