Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@dameng324
Copy link
Owner

This pull request introduces diagnostics and improved handling for default values in proto members, especially focusing on deserialization issues that can arise when members have default values. It adds a new warning (LIGHT_PROTO_W001), updates the code generation logic to report this warning, and enhances error handling for readonly and init-only members. There are also some improvements and bug fixes for .NET 8+ compatibility and readonly member assignment.

Key changes include:

Diagnostics and Warnings:

  • Added documentation for the new warning LIGHT_PROTO_W001, which informs users that members with default values may break deserialization, and suggests solutions.
  • Implemented code to emit LIGHT_PROTO_W001 as a diagnostic warning when a value type proto member has a default value and SkipConstructor is not set. [1] [2]
  • Added a suppression for LIGHT_PROTO_W001 in InitializerTests to avoid test noise.

Code Generation and Error Handling Improvements:

  • Refactored generator logic to pass SourceProductionContext for improved diagnostic reporting and error handling throughout proto contract and member processing. [1] [2] [3] [4] [5] [6] [7]
  • Improved error messages and introduced new exceptions for cases such as missing parameterless constructors, inability to initialize readonly members, and failure to find backing fields for readonly properties. [1] [2] [3] [4]

.NET 8+ Compatibility:

  • Adjusted code generation to use UnsafeAccessor for assigning readonly members on .NET 8+, and to fallback to previous mechanisms on earlier versions. [1] [2] [3] [4] [5]

Bug Fixes and Minor Improvements:

  • Fixed a nullability issue in a test by using null-conditional operators for StringBuilderField.

These changes collectively improve the robustness of the code generator, provide clearer diagnostics to users, and ensure better compatibility and safety across different .NET versions.

Fixes: #144
Fixes: #143

Introduces LIGHT_PROTO_W001 diagnostic to warn when a value type member has a default value that may cause unexpected deserialization results if SkipConstructor is not set. Updates generator logic to report this warning, adds documentation, and adjusts related tests to suppress or handle the warning.
Copilot AI review requested due to automatic review settings January 9, 2026 07:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request enhances the LightProto code generator to better handle readonly and init-only members, especially in .NET 8+. It introduces new diagnostics for default values that may cause deserialization issues, improves error handling, and adds support for using UnsafeAccessor to initialize readonly members on .NET 8+.

Key changes:

  • Added new warning LIGHT_PROTO_W001 to alert users when value type members have default values that may break deserialization
  • Implemented UnsafeAccessor-based initialization for readonly/init-only members on .NET 8+, with fallback behavior on earlier versions
  • Improved error messages and added validation for parameterless constructors

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
src/LightProto.Generator/LightProtoGenerator.cs Core generator changes: added SourceProductionContext threading, UnsafeAccessor implementation, new warning diagnostic, improved error handling
docs/Diagnostic.md Documentation for new LIGHT_PROTO_W001 warning with examples and fixes
tests/LightProto.Tests/Parsers/SkipConstructorWithReadonlyFieldTests.cs New test for SkipConstructor with readonly fields
tests/LightProto.Tests/Parsers/SkipConstructorFalseWithReadonlyFieldTests.cs New test for normal constructor with readonly fields
tests/LightProto.Tests/Parsers/SkipConstructorWithInitializerTests.cs Removed NET7_0_OR_GREATER conditional compilation (not needed for this test)
tests/LightProto.Tests/Parsers/SkipConstructorTests.cs Removed NET7_0_OR_GREATER conditional compilation (not needed for this test)
tests/LightProto.Tests/Parsers/InitializerTests.cs Added suppression for LIGHT_PROTO_W001 warning
tests/LightProto.Tests/CsPackage.cs Added null-conditional operators for safer StringBuilder comparison
tests/TestAot/TestAot.csproj Added protobuf-net package reference for compatibility testing

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov
Copy link

codecov bot commented Jan 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.39%. Comparing base (f6ee2ff) to head (5da5c7f).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #149   +/-   ##
=======================================
  Coverage   98.39%   98.39%           
=======================================
  Files          99       99           
  Lines        2186     2186           
  Branches      231      231           
=======================================
  Hits         2151     2151           
  Misses         23       23           
  Partials       12       12           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

This comment has been minimized.

Renamed Diagnostic.md to Diagnostics.md and fixed typos in the documentation. Updated LightProtoGenerator to improve boolean expression clarity, error messages, and help link references. Changed test preprocessor directives from NET7_0_OR_GREATER to NET8_0_OR_GREATER for relevant test files.
@github-actions
Copy link

github-actions bot commented Jan 9, 2026


BenchmarkDotNet v0.15.3, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.101
  [Host]    : .NET 8.0.22 (8.0.22, 8.0.2225.52707), X64 RyuJIT x86-64-v3
  .NET 10.0 : .NET 10.0.1 (10.0.1, 10.0.125.57005), X64 RyuJIT x86-64-v3
  .NET 8.0  : .NET 8.0.22 (8.0.22, 8.0.2225.52707), X64 RyuJIT x86-64-v3
  .NET 9.0  : .NET 9.0.11 (9.0.11, 9.0.1125.51716), X64 RyuJIT x86-64-v3


Method Job Runtime Mean Error StdDev Ratio Allocated Alloc Ratio
Deserialize_ProtoBuf_net .NET 10.0 .NET 10.0 762.8 μs 5.42 μs 4.80 μs 1.34 562 KB 0.98
Deserialize_GoogleProtoBuf .NET 10.0 .NET 10.0 636.1 μs 4.69 μs 4.15 μs 1.12 648.7 KB 1.13
Deserialize_LightProto .NET 10.0 .NET 10.0 568.1 μs 5.47 μs 5.11 μs 1.00 574.8 KB 1.00
Deserialize_ProtoBuf_net .NET 8.0 .NET 8.0 896.9 μs 6.65 μs 6.22 μs 1.45 562 KB 0.98
Deserialize_GoogleProtoBuf .NET 8.0 .NET 8.0 823.6 μs 5.71 μs 4.77 μs 1.33 648.7 KB 1.13
Deserialize_LightProto .NET 8.0 .NET 8.0 617.3 μs 3.74 μs 3.50 μs 1.00 574.8 KB 1.00
Deserialize_ProtoBuf_net .NET 9.0 .NET 9.0 860.5 μs 3.07 μs 2.72 μs 1.45 562 KB 0.98
Deserialize_GoogleProtoBuf .NET 9.0 .NET 9.0 732.2 μs 6.37 μs 5.96 μs 1.24 648.7 KB 1.13
Deserialize_LightProto .NET 9.0 .NET 9.0 592.1 μs 4.25 μs 3.55 μs 1.00 574.8 KB 1.00

BenchmarkDotNet v0.15.3, Linux Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores
.NET SDK 10.0.101
  [Host]    : .NET 8.0.22 (8.0.22, 8.0.2225.52707), X64 RyuJIT x86-64-v3
  .NET 10.0 : .NET 10.0.1 (10.0.1, 10.0.125.57005), X64 RyuJIT x86-64-v3
  .NET 8.0  : .NET 8.0.22 (8.0.22, 8.0.2225.52707), X64 RyuJIT x86-64-v3
  .NET 9.0  : .NET 9.0.11 (9.0.11, 9.0.1125.51716), X64 RyuJIT x86-64-v3


Method Job Runtime Mean Error StdDev Ratio Allocated Alloc Ratio
Serialize_ProtoBuf_net .NET 10.0 .NET 10.0 912.0 μs 7.71 μs 6.44 μs 1.31 526.4 KB 1.03
Serialize_GoogleProtoBuf .NET 10.0 .NET 10.0 790.2 μs 3.69 μs 3.08 μs 1.14 512.95 KB 1.00
Serialize_LightProto .NET 10.0 .NET 10.0 695.0 μs 2.83 μs 2.37 μs 1.00 512.92 KB 1.00
Serialize_ProtoBuf_net .NET 8.0 .NET 8.0 1,069.9 μs 10.36 μs 9.18 μs 1.39 526.4 KB 1.03
Serialize_GoogleProtoBuf .NET 8.0 .NET 8.0 814.7 μs 6.63 μs 5.88 μs 1.06 512.95 KB 1.00
Serialize_LightProto .NET 8.0 .NET 8.0 767.7 μs 3.59 μs 3.18 μs 1.00 512.92 KB 1.00
Serialize_ProtoBuf_net .NET 9.0 .NET 9.0 976.5 μs 5.57 μs 4.94 μs 1.26 526.41 KB 1.03
Serialize_GoogleProtoBuf .NET 9.0 .NET 9.0 808.4 μs 4.85 μs 4.05 μs 1.05 512.95 KB 1.00
Serialize_LightProto .NET 9.0 .NET 9.0 773.2 μs 3.93 μs 3.49 μs 1.00 512.92 KB 1.00

@dameng324 dameng324 merged commit 4ede691 into main Jan 9, 2026
8 checks passed
@dameng324 dameng324 deleted the use-unsafe-accessor-Initialize-readonly-member branch January 9, 2026 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants