Skip to content

Commit 54274cf

Browse files
Additional comments.
1 parent cc3df6a commit 54274cf

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

src/libraries/System.Text.Json/src/System/Text/Json/Schema/JsonSchemaExporter.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,22 @@ private static JsonSchema MapJsonSchemaCore(
7878

7979
if (cacheResult && state.TryPushType(typeInfo, propertyInfo, out string? existingJsonPointer))
8080
{
81-
// Schema for type has already been generated, return a reference to it.
81+
// We're generating the schema of a recursive type, return a reference pointing to the outermost schema.
8282
return CompleteSchema(ref state, new JsonSchema { Ref = existingJsonPointer });
8383
}
8484

8585
JsonConverter effectiveConverter = customConverter ?? typeInfo.Converter;
8686
JsonNumberHandling effectiveNumberHandling = customNumberHandling ?? typeInfo.NumberHandling ?? typeInfo.Options.NumberHandling;
8787
if (effectiveConverter.GetSchema(effectiveNumberHandling) is { } schema)
8888
{
89+
// A schema has been provided by the converter.
8990
return CompleteSchema(ref state, schema);
9091
}
9192

9293
if (parentPolymorphicType is null && typeInfo.PolymorphismOptions is { DerivedTypes.Count: > 0 } polyOptions)
9394
{
9495
// This is the base type of a polymorphic type hierarchy. The schema for this type
9596
// will include an "anyOf" property with the schemas for all derived types.
96-
9797
string typeDiscriminatorKey = polyOptions.TypeDiscriminatorPropertyName;
9898
List<JsonDerivedType> derivedTypes = new(polyOptions.DerivedTypes);
9999

@@ -141,7 +141,7 @@ private static JsonSchema MapJsonSchemaCore(
141141

142142
state.PopSchemaNode();
143143

144-
// Determine if all derived types have the same schema type.
144+
// Determine if all derived schemas have the same type.
145145
if (anyOf.Count == 0)
146146
{
147147
schemaType = derivedSchema.Type;
@@ -245,6 +245,9 @@ private static JsonSchema MapJsonSchemaCore(
245245

246246
(properties ??= []).Add(new(property.Name, propertySchema));
247247

248+
// Mark as required if either the property is required or the associated constructor parameter is non-optional.
249+
// While the latter implies the former in cases where the JsonSerializerOptions.RespectRequiredConstructorParameters
250+
// setting has been enabled, for the case of the schema exporter we always mark non-optional constructor parameters as required.
248251
if (property is { IsRequired: true } or { AssociatedParameter.IsRequiredParameter: true })
249252
{
250253
(required ??= []).Add(property.Name);
@@ -340,13 +343,17 @@ private static JsonSchema MapJsonSchemaCore(
340343

341344
default:
342345
Debug.Assert(typeInfo.Kind is JsonTypeInfoKind.None);
346+
// Return a `true` schema for types with user-defined converters.
343347
return CompleteSchema(ref state, JsonSchema.True);
344348
}
345349

346350
JsonSchema CompleteSchema(ref GenerationState state, JsonSchema schema)
347351
{
348352
if (schema.Ref is null)
349353
{
354+
// A schema is marked as nullable if either
355+
// 1. We have a schema for a property where either the getter or setter are marked as nullable.
356+
// 2. We have a schema for a reference type, unless we're explicitly treating null-oblivious types as non-nullable.
350357
bool isNullableSchema = propertyInfo != null
351358
? propertyInfo.IsGetNullable || propertyInfo.IsSetNullable
352359
: typeInfo.CanBeNull && !parentPolymorphicTypeIsNonNullable && !state.ExporterOptions.TreatNullObliviousAsNonNullable;
@@ -364,6 +371,7 @@ JsonSchema CompleteSchema(ref GenerationState state, JsonSchema schema)
364371

365372
if (state.ExporterOptions.TransformSchemaNode != null)
366373
{
374+
// Prime the schema for invocation by the JsonNode transformer.
367375
schema.ExporterContext = state.CreateContext(typeInfo, propertyInfo);
368376
}
369377

0 commit comments

Comments
 (0)