First implementation of C# nullable reference types enablement using the current (unreleased) edition.

PiperOrigin-RevId: 926073660
This commit is contained in:
Protobuf Team Bot 2026-06-03 09:19:16 -07:00 committed by Copybara-Service
parent 992e3acc4c
commit 7a732d1fb8
20 changed files with 949 additions and 44 deletions

View file

@ -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"/>

View file

@ -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 \

View file

@ -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" }
];
}

55
csharp/protos/nrt.proto Normal file
View file

@ -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;
}

View file

@ -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);
}