[release/6.0-rc2] Update source-gen APIs according to review #59243
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Backport of #59042 to release/6.0-rc2
/cc @layomia
Customer Impact
Refactors the APIs that JSON-source-generated output calls to make them more resilient to forward versioning. Taking this change means that it will be easier to add new features to the source generator in future versions of STJ to satisfy our customers, including existing features offered by the reflection-based serializer that we were not able to get src-gen support for in .NET 6.0. Taking this change helps avoid the APIs that we are shipping as-is in 6.0 from becoming instant legacy and dead weight in user applications.
Changes are generally of this form:
Here we are encapsulating a bunch of method parameters on the
CreatePropertyInfo<T>
method into their own dedicatedJsonPropertyInfoValues<T>
class which allows us to simply add a new property on the class to support a new feature, rather than needing a new overload of theCreatePropertyInfo<T>
. This is a much cleaner design that helps reduce the likelihood complex deprecations in the future. We are very likely to add new features to JsonSerializer in .NET 7 and beyond. We are not blocked on doing this with the current API shape, but the implementation would be less than ideal.For instance, if we wanted to implement a new “[JsonRequired]” feature to indicate that a property needs a value when deserialization, we would need to add a new overload to the CreatePropertyInfo(...) method accepting a new
bool isRequired
parameter. We would likely need a new overload on every release of STJ, leading to a lot of cruft over time. The ideal way supported by the new API shape is simply to add a newbool IsRequired { get; init; }
property to the JsonPropertyInfoValues class. This is more maintainable over multiple releases.This PR also adds support for the src-gen
JsonSerializer
implementation interop-ing with theSystem.Text.Json.Nodes
types. This was done for completeness to align with approved API for 6.0, and also add src-gen support for these popular types. These changes are not essential to the goal of this PR, but the risk with the associated changes is really low as backed by associated tests.Testing
The new API shape is fully covered by way of existing tests for current functionality.
Risk
With respect to test/program failures, the risk with this change is low since it is largely cosmetic - the same metadata is being passed to the serializer, just in a cleaner way. The tests in the
System.Text.Json.SourceGeneration.*Tests
projects exercise the new code thoroughly. Pre-existing non src-genJsonSerializer
functionality is completely unaffected by this change.This is a binary-compat breaking change between RC1/2 - users would need to recompile their applications to avoid runtime exceptions when using a newer version of the SDK. A breaking change doc would need to be published and advertised.
Documentation for these APIs would need to updated outside of the normal doc channels. However, a new pass at the metadata APIs is already planned, to call out to users that these APIs are only meant to be consumed by the source generator. If this change is accepted, these doc updates would be made together. cc @carlossanlop
Code flow
I looked through our downstream consumers and identified two projects that use the source generator, both for benchmarks:
I confirmed that they are always recompiled when the latest bits of the runtime flow in. This means that they shouldn’t experience any breaking changes. If we proceed, I’ll look out for downstream integration and help fix up any issues if they do arise. cc @pranavkm @sebastienros