Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e0f3773
feat: use lazy get for collection initialization to reduce resource a…
MaggieKimani1 Mar 24, 2025
3b370e5
chore: use Lazy<T> pattern; preserve null values
MaggieKimani1 Mar 25, 2025
ef7a150
chore: replicate for collections in other components
MaggieKimani1 Mar 25, 2025
205e6a1
chore: remove unnecessary usings
MaggieKimani1 Mar 25, 2025
915e747
fix: revert lazy initialization; remove collection initialization
MaggieKimani1 Mar 26, 2025
0a65a54
chore: initialize collections to prevent NREs
MaggieKimani1 Mar 26, 2025
00e0913
chore: fix failing tests
MaggieKimani1 Mar 26, 2025
0921b0d
chore: merge remote-tracking branch 'origin/feat/memory-perf-improvem…
MaggieKimani1 Mar 26, 2025
796d49c
chore: revert changes
MaggieKimani1 Mar 26, 2025
08cc754
chore: merge main into current branch
MaggieKimani1 Apr 1, 2025
6fff3c5
chore: remove default collection initialization across all models; cl…
MaggieKimani1 Apr 1, 2025
1fa4647
chore: merge main into current branch
MaggieKimani1 Apr 2, 2025
4e97803
chore: clean up code; initialize collections where applicable
MaggieKimani1 Apr 3, 2025
eabd01d
chore: more cleanup
MaggieKimani1 Apr 3, 2025
c035940
chore: move assignment within the condition
MaggieKimani1 Apr 3, 2025
a28aa21
chore: replace interface with concrete type
MaggieKimani1 Apr 6, 2025
5686de4
chore: simplify collection initialization
MaggieKimani1 Apr 7, 2025
ccfeab1
Update src/Microsoft.OpenApi/Models/OpenApiPathItem.cs
MaggieKimani1 Apr 7, 2025
ad46bdb
chore: implement PR feedback
MaggieKimani1 Apr 7, 2025
d12efaf
chore: pull changes in remote branch
MaggieKimani1 Apr 7, 2025
cb879e3
chore: reverts casing change
baywet Apr 8, 2025
e8dc71e
Merge branch 'main' into feat/memory-perf-improvements
baywet Apr 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT license.

using System;
using System.Collections.Generic;
using Microsoft.OpenApi.Exceptions;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
Expand Down Expand Up @@ -32,10 +33,8 @@ public static void AddExtension<T>(this T element, string name, IOpenApiExtensio
throw new OpenApiException(string.Format(SRResource.ExtensionFieldNameMustBeginWithXDash, name));
}

if (element.Extensions is not null)
{
element.Extensions[name] = Utils.CheckArgumentNull(any);
}
element.Extensions ??= new Dictionary<string, IOpenApiExtension>();
element.Extensions[name] = Utils.CheckArgumentNull(any);
}
}
}
40 changes: 20 additions & 20 deletions src/Microsoft.OpenApi/Models/OpenApiSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,19 +173,19 @@ public decimal? Minimum
public bool WriteOnly { get; set; }

/// <inheritdoc />
public IList<IOpenApiSchema>? AllOf { get; set; } = [];
public IList<IOpenApiSchema>? AllOf { get; set; }

/// <inheritdoc />
public IList<IOpenApiSchema>? OneOf { get; set; } = [];
public IList<IOpenApiSchema>? OneOf { get; set; }

/// <inheritdoc />
public IList<IOpenApiSchema>? AnyOf { get; set; } = [];
public IList<IOpenApiSchema>? AnyOf { get; set; }

/// <inheritdoc />
public IOpenApiSchema? Not { get; set; }

/// <inheritdoc />
public ISet<string>? Required { get; set; } = new HashSet<string>();
public ISet<string>? Required { get; set; }
Comment thread
MaggieKimani1 marked this conversation as resolved.
Outdated

/// <inheritdoc />
public IOpenApiSchema? Items { get; set; }
Expand All @@ -200,10 +200,10 @@ public decimal? Minimum
public bool? UniqueItems { get; set; }

/// <inheritdoc />
public IDictionary<string, IOpenApiSchema>? Properties { get; set; } = new Dictionary<string, IOpenApiSchema>(StringComparer.Ordinal);
public IDictionary<string, IOpenApiSchema>? Properties { get; set; }

/// <inheritdoc />
public IDictionary<string, IOpenApiSchema>? PatternProperties { get; set; } = new Dictionary<string, IOpenApiSchema>(StringComparer.Ordinal);
public IDictionary<string, IOpenApiSchema>? PatternProperties { get; set; }

/// <inheritdoc />
public int? MaxProperties { get; set; }
Expand All @@ -227,10 +227,10 @@ public decimal? Minimum
public IList<JsonNode>? Examples { get; set; }

/// <inheritdoc />
public IList<JsonNode>? Enum { get; set; } = new List<JsonNode>();
public IList<JsonNode>? Enum { get; set; }

/// <inheritdoc />
public bool UnevaluatedProperties { get; set;}
public bool UnevaluatedProperties { get; set; }

/// <inheritdoc />
public OpenApiExternalDocs? ExternalDocs { get; set; }
Expand All @@ -242,16 +242,16 @@ public decimal? Minimum
public OpenApiXml? Xml { get; set; }

/// <inheritdoc />
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <inheritdoc />
public IDictionary<string, JsonNode>? UnrecognizedKeywords { get; set; } = new Dictionary<string, JsonNode>();
public IDictionary<string, JsonNode>? UnrecognizedKeywords { get; set; }

/// <inheritdoc />
public IDictionary<string, object>? Annotations { get; set; }

/// <inheritdoc />
public IDictionary<string, ISet<string>>? DependentRequired { get; set; } = new Dictionary<string, ISet<string>>();
public IDictionary<string, ISet<string>>? DependentRequired { get; set; }

/// <summary>
/// Parameterless constructor
Expand Down Expand Up @@ -309,7 +309,7 @@ internal OpenApiSchema(IOpenApiSchema schema)
MinProperties = schema.MinProperties ?? MinProperties;
AdditionalPropertiesAllowed = schema.AdditionalPropertiesAllowed;
AdditionalProperties = schema.AdditionalProperties?.CreateShallowCopy();
Discriminator = schema.Discriminator != null ? new(schema.Discriminator) : null;
Discriminator = schema.Discriminator != null ? new(schema.Discriminator) : null;
Example = schema.Example != null ? JsonNodeCloneHelper.Clone(schema.Example) : null;
Examples = schema.Examples != null ? new List<JsonNode>(schema.Examples) : null;
Enum = schema.Enum != null ? new List<JsonNode>(schema.Enum) : null;
Expand Down Expand Up @@ -421,7 +421,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
writer.WriteProperty(OpenApiConstants.MinProperties, MinProperties);

// required
writer.WriteOptionalCollection(OpenApiConstants.Required, Required, (w, s) =>
writer.WriteOptionalCollection(OpenApiConstants.Required, Required, (w, s) =>
{
if (!string.IsNullOrEmpty(s) && s is not null)
{
Expand Down Expand Up @@ -502,7 +502,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
// Unrecognized keywords
if (UnrecognizedKeywords is not null && UnrecognizedKeywords.Any())
{
writer.WriteOptionalMap(OpenApiConstants.UnrecognizedKeywords, UnrecognizedKeywords, (w,s) => w.WriteAny(s));
writer.WriteOptionalMap(OpenApiConstants.UnrecognizedKeywords, UnrecognizedKeywords, (w, s) => w.WriteAny(s));
}

writer.WriteEndObject();
Expand Down Expand Up @@ -665,7 +665,7 @@ private void SerializeAsV2(
writer.WriteProperty(OpenApiConstants.MinProperties, MinProperties);

// required
writer.WriteOptionalCollection(OpenApiConstants.Required, Required, (w, s) =>
writer.WriteOptionalCollection(OpenApiConstants.Required, Required, (w, s) =>
{
if (!string.IsNullOrEmpty(s) && s is not null)
{
Expand Down Expand Up @@ -749,7 +749,7 @@ private void SerializeTypeProperty(JsonSchemaType? type, IOpenApiWriter writer,
// check whether nullable is true for upcasting purposes
var isNullable = (Type.HasValue && Type.Value.HasFlag(JsonSchemaType.Null)) ||
Extensions is not null &&
Extensions.TryGetValue(OpenApiConstants.NullableExtension, out var nullExtRawValue) &&
Extensions.TryGetValue(OpenApiConstants.NullableExtension, out var nullExtRawValue) &&
nullExtRawValue is OpenApiAny { Node: JsonNode jsonNode } &&
jsonNode.GetValueKind() is JsonValueKind.True;
if (type is null)
Expand All @@ -761,7 +761,7 @@ Extensions is not null &&
}
else if (!HasMultipleTypes(type.Value))
{

switch (version)
{
case OpenApiSpecVersion.OpenApi3_1 when isNullable:
Expand Down Expand Up @@ -794,13 +794,13 @@ where type.Value.HasFlag(flag)
select flag).ToList();
writer.WriteOptionalCollection(OpenApiConstants.Type, list, (w, s) =>
{
foreach(var item in s.ToIdentifiers())
foreach (var item in s.ToIdentifiers())
{
w.WriteValue(item);
}
});
}
}
}
}

private static bool IsPowerOfTwo(int x)
Expand All @@ -824,7 +824,7 @@ where temporaryType.HasFlag(flag)
select flag.ToFirstIdentifier()).ToList();
if (list.Count > 1)
{
writer.WriteOptionalCollection(OpenApiConstants.Type, list, (w, s) =>
writer.WriteOptionalCollection(OpenApiConstants.Type, list, (w, s) =>
{
if (!string.IsNullOrEmpty(s) && s is not null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.Json.Nodes;

namespace Microsoft.OpenApi.Reader.V31
{
Expand Down Expand Up @@ -382,8 +383,9 @@ public static IOpenApiSchema LoadSchema(ParseNode node, OpenApiDocument hostDocu
{
propertyNode.ParseField(schema, _openApiSchemaFixedFields, _openApiSchemaPatternFields, hostDocument);
}
else if (schema.UnrecognizedKeywords is not null && propertyNode.JsonNode is not null)
else if (propertyNode.JsonNode is not null)
{
schema.UnrecognizedKeywords ??= new Dictionary<string, JsonNode>(StringComparer.Ordinal);
Comment thread
baywet marked this conversation as resolved.
schema.UnrecognizedKeywords[propertyNode.Name] = propertyNode.JsonNode;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public static bool ValidateChildSchemaAgainstDiscriminator(IOpenApiSchema schema
{
if (discriminatorName is not null)
{
if (!schema.Required?.Contains(discriminatorName) ?? false)
if (schema.Required is null || !schema.Required.Contains(discriminatorName))
{
// recursively check nested schema.OneOf, schema.AnyOf or schema.AllOf and their required fields for the discriminator
if (schema.OneOf?.Count != 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ public void ParseHeaderWithEnumShouldSucceed()
Type = JsonSchemaType.Number,
Format = "float",
Enum =
{
[
new OpenApiAny(7).Node,
new OpenApiAny(8).Node,
new OpenApiAny(9).Node
}
]
}
}, options => options.IgnoringCyclicReferences()
.Excluding((IMemberInfo memberInfo) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ public async Task SerializesBodyReferencesWorks()
openApiDocument.AddComponent("UserSchema", new OpenApiSchema
{
Type = JsonSchemaType.Object,
Properties =
Properties = new Dictionary<string, IOpenApiSchema>
{
["name"] = new OpenApiSchema
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,11 @@ public void ParseParameterWithEnumShouldSucceed()
Type = JsonSchemaType.Number,
Format = "float",
Enum =
{
new OpenApiAny(7).Node,
new OpenApiAny(8).Node,
new OpenApiAny(9).Node
}
[
new OpenApiAny(7).Node,
new OpenApiAny(8).Node,
new OpenApiAny(9).Node
]
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
using System.Linq;
using System.Net.Http;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Models.Interfaces;
using Microsoft.OpenApi.Reader.ParseNodes;
using Microsoft.OpenApi.Reader.V2;
using Microsoft.OpenApi.Writers;
using Xunit;

namespace Microsoft.OpenApi.Readers.Tests.V2Tests
Expand Down Expand Up @@ -69,7 +71,7 @@ public class OpenApiPathItemTests
Schema = new OpenApiSchema()
{
Type = JsonSchemaType.Object,
Properties =
Properties = new Dictionary<string, IOpenApiSchema>
{
["name"] = new OpenApiSchema()
{
Expand All @@ -93,7 +95,7 @@ public class OpenApiPathItemTests
Schema = new OpenApiSchema()
{
Type = JsonSchemaType.Object,
Properties =
Properties = new Dictionary<string, IOpenApiSchema>
{
["name"] = new OpenApiSchema()
{
Expand Down Expand Up @@ -175,7 +177,7 @@ public class OpenApiPathItemTests
Schema = new OpenApiSchema()
{
Type = JsonSchemaType.Object,
Properties =
Properties = new Dictionary<string, IOpenApiSchema>
{
["name"] = new OpenApiSchema()
{
Expand Down Expand Up @@ -204,7 +206,7 @@ public class OpenApiPathItemTests
Schema = new OpenApiSchema()
{
Type = JsonSchemaType.Object,
Properties =
Properties = new Dictionary<string, IOpenApiSchema>
{
["name"] = new OpenApiSchema()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1247,7 +1247,7 @@ public async Task SerializesDoubleHopeReferences()
{
Type = JsonSchemaType.Object,
Description = "A pet",
Properties =
Properties = new Dictionary<string, IOpenApiSchema>
{
["id"] = new OpenApiSchema
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ public async Task ParseQueryParameterWithObjectTypeAndContentShouldSucceed()
Schema = new OpenApiSchema()
{
Type = JsonSchemaType.Object,
Required =
Required = new HashSet<string>
{
"lat",
"long"
},
Properties =
Properties = new Dictionary<string, IOpenApiSchema>
{
["lat"] = new OpenApiSchema()
{
Expand Down
Loading