First implementation of C# nullable reference types enablement using the current (unreleased) edition. PiperOrigin-RevId: 897682871
diff --git a/MODULE.bazel b/MODULE.bazel index 04a8b56..8848636 100644 --- a/MODULE.bazel +++ b/MODULE.bazel
@@ -24,7 +24,7 @@ #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 02e3a62..2cb5ec0 100644 --- a/csharp/Google.Protobuf.Tools.nuspec +++ b/csharp/Google.Protobuf.Tools.nuspec
@@ -23,8 +23,8 @@ <file src="protoc/linux_aarch64/protoc" target="tools/linux_aarch64/protoc"/> <file src="protoc/macosx_x64/protoc" target="tools/macosx_x64/protoc"/> <!-- - - Include the protos for the well-known types in a directory where protoc will - - find them by default. + - Include the protos for the well-known types and language-specific editions features in a + - directory where protoc will find them by default. --> <file src="src/google/protobuf/any.proto" target="tools/include/google/protobuf"/> <file src="src/google/protobuf/api.proto" target="tools/include/google/protobuf"/> @@ -37,9 +37,11 @@ <file src="src/google/protobuf/timestamp.proto" target="tools/include/google/protobuf"/> <file src="src/google/protobuf/type.proto" target="tools/include/google/protobuf"/> <file src="src/google/protobuf/wrappers.proto" target="tools/include/google/protobuf"/> + <file src="csharp/google/protobuf/c_sharp_features.proto" target="tools/include/google/protobuf"/> <!-- - Include the protos for the well-known types again in their old location, - - for backward compatibility. + - for backward compatibility. This does not include features files, as those have never been + - in tools/google/protobuf directory. --> <file src="src/google/protobuf/any.proto" target="tools/google/protobuf"/> <file src="src/google/protobuf/api.proto" target="tools/google/protobuf"/>
diff --git a/csharp/generate_protos.sh b/csharp/generate_protos.sh index a2e9b3a..615e45c 100755 --- a/csharp/generate_protos.sh +++ b/csharp/generate_protos.sh
@@ -67,6 +67,7 @@ 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 eb9af73..f26300f 100644 --- a/csharp/google/protobuf/c_sharp_features.proto +++ b/csharp/google/protobuf/c_sharp_features.proto
@@ -20,4 +20,17 @@ } 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 0000000..00b7f22 --- /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 f15da61..0b29472 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 @@ // "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:{testProtosOutputDir}\\Google.Protobuf.dll -out:{testProtosOutputDir}\\TestProtos.RefStructCompatibilityTest.OldCompiler.dll {sources}"; + var args = $"-langversion:3 -nologo -nowarn:1691 -target:library {compatibilityFlag} -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 ab848dc..464407c 100644 --- a/examples/MODULE.bazel +++ b/examples/MODULE.bazel
@@ -19,7 +19,7 @@ ) 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 c590bc9..72785fb 100644 --- a/protobuf_deps.bzl +++ b/protobuf_deps.bzl
@@ -103,9 +103,9 @@ 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 6bb9d6a..0560cde 100644 --- a/src/google/protobuf/compiler/csharp/BUILD.bazel +++ b/src/google/protobuf/compiler/csharp/BUILD.bazel
@@ -69,6 +69,7 @@ "//src/google/protobuf/compiler:__pkg__", ], deps = [ + ":csharp_features_bootstrap", ":names", "//src/google/protobuf", "//src/google/protobuf:port", @@ -126,6 +127,22 @@ ], ) +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 0000000..6dd7005 --- /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 <algorithm> +#include <type_traits> +#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<CSharpFeatures>()._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<bool, offsetof(CSharpFeatures, _impl_.nullable_reference_types_), 0>(), + {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 <typename> +constexpr CSharpFeatures::CSharpFeatures(::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) + : ::google::protobuf::Message( +#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, + ::google::protobuf::Message::GetNewImpl<CSharpFeatures>(), +#if defined(PROTOBUF_CUSTOM_VTABLE) + &CSharpFeatures::SharedDtor, + ::google::protobuf::Message::GetClearImpl<CSharpFeatures>(), &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<CSharpFeatures>( + GetClassData())) +#endif // PROTOBUF_MESSAGE_GLOBALS + { + } + ~CSharpFeaturesGlobalsTypeInternal() {} + union { + alignas(::_pbi::kMaxMessageAlignment) CSharpFeatures _default; + }; +#ifdef PROTOBUF_MESSAGE_GLOBALS + decltype(::_pbi::PrivateAccess::GenerateParseTable<CSharpFeatures>( + ::std::declval<const ::_pbi::ClassData*>())) _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) + : ::google::protobuf::Message(arena, CSharpFeatures_get_class_data()) { +#else // PROTOBUF_CUSTOM_VTABLE + : ::google::protobuf::Message(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) + : ::google::protobuf::Message(arena, CSharpFeatures_get_class_data()), +#else // PROTOBUF_CUSTOM_VTABLE + : ::google::protobuf::Message(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<CSharpFeatures&>(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<const CSharpFeatures&>(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<const CSharpFeatures&>(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<bool>(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<CSharpFeatures*>(&to_msg); + auto& from = static_cast<const CSharpFeatures&>(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 ::google::protobuf::Message::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 0000000..4489e04 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/c_sharp_features.pb.h
@@ -0,0 +1,347 @@ +// 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 <limits> +#include <string> +#include <type_traits> +#include <utility> + +// 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 + +namespace google { +namespace protobuf { +namespace internal { +template <typename T> +::absl::string_view GetAnyMessageName(); +} // namespace internal +} // namespace protobuf +} // namespace google + +// 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) */ { + 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 <typename = void> + 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>(&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 ::google::protobuf::Message::DefaultConstruct<CSharpFeatures>(arena); + } + using ::google::protobuf::Message::CopyFrom; + void CopyFrom(const CSharpFeatures& from); + using ::google::protobuf::Message::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: + template <typename T> + friend ::absl::string_view(::google::protobuf::internal::GetAnyMessageName)(); + 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 <typename T> + 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 290b38c..dd3b7a7 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 @@ 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 @@ } (*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 @@ : SourceGeneratorBase(options), descriptor_(descriptor), presenceIndex_(presenceIndex) { + nrt_enabled_ = Generator::GetResolvedSourceFeatures(*descriptor->file()) + .GetExtension(pb::csharp) + .nullable_reference_types(); SetCommonFieldVariables(&variables_); } @@ -216,10 +226,12 @@ 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 39db3aa..c3347d7 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 @@ protected: const FieldDescriptor* descriptor_; const int presenceIndex_; + // NRT = Nullable Reference Types + bool nrt_enabled_; absl::flat_hash_map<absl::string_view, std::string> 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 8fa15e5..84c7c1e 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 <string> +#include <vector> #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 @@ Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; } Edition GetMaximumEdition() const override { return Edition::EDITION_2024; } using CodeGenerator::GetEdition; + + std::vector<const FieldDescriptor*> 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 d80b514..8c2b0b4 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 <algorithm> -#include <sstream> #include <string> #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 @@ } } 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 @@ absl::flat_hash_map<absl::string_view, std::string> 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 @@ "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 @@ "TValue> extension) {\n" " return pb::ExtensionSet.Get(ref _extensions, extension);\n" "}\n" - "public pbc::RepeatedField<TValue> " + "public pbc::RepeatedField<TValue>$nrt_annotation$ " "GetExtension<TValue>(pb::RepeatedExtension<$class_name$, TValue> " "extension) {\n" " return pb::ExtensionSet.Get(ref _extensions, extension);\n" @@ -417,16 +423,17 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { absl::flat_hash_map<absl::string_view, std::string> 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 96e47b3..abaac58 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.h +++ b/src/google/protobuf/compiler/csharp/csharp_message.h
@@ -40,6 +40,8 @@ std::vector<const FieldDescriptor*> 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 0e6eee7..2c3f093 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() = 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 @@ 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 1ed4c9f..58309d3 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 @@ 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 2194dc5..e1af11d 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 @@ 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 @@ printer->Print("\n"); } + if (nrt_enabled_) { + printer->Print("#nullable enable annotations\n"); + } + printer->Print( "/// <summary>Holder for reflection information generated from $file_name$</summary>\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 af29bf8..306b665 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 @@ 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);