Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 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);
}
}
}
5 changes: 2 additions & 3 deletions src/Microsoft.OpenApi/Models/OpenApiCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,16 @@ namespace Microsoft.OpenApi.Models
/// <summary>
/// Callback Object: A map of possible out-of band callbacks related to the parent operation.
/// </summary>
public class OpenApiCallback : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiCallback
public class OpenApiCallback : IOpenApiExtensible, IOpenApiCallback
{
/// <inheritdoc/>
public Dictionary<RuntimeExpression, IOpenApiPathItem>? PathItems { get; set; }
= [];


/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <summary>
/// Parameter-less constructor
Expand Down
27 changes: 12 additions & 15 deletions src/Microsoft.OpenApi/Models/OpenApiComponents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,60 +19,57 @@ public class OpenApiComponents : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// An object to hold reusable <see cref="IOpenApiSchema"/> Objects.
/// </summary>
public IDictionary<string, IOpenApiSchema>? Schemas { get; set; } = new Dictionary<string, IOpenApiSchema>();
public IDictionary<string, IOpenApiSchema>? Schemas { get; set; }

/// <summary>
/// An object to hold reusable <see cref="IOpenApiResponse"/> Objects.
/// </summary>
public IDictionary<string, IOpenApiResponse>? Responses { get; set; } = new Dictionary<string, IOpenApiResponse>();
public IDictionary<string, IOpenApiResponse>? Responses { get; set; }

/// <summary>
/// An object to hold reusable <see cref="IOpenApiParameter"/> Objects.
/// </summary>
public IDictionary<string, IOpenApiParameter>? Parameters { get; set; } =
new Dictionary<string, IOpenApiParameter>();
public IDictionary<string, IOpenApiParameter>? Parameters { get; set; }

/// <summary>
/// An object to hold reusable <see cref="OpenApiExample"/> Objects.
/// </summary>
public IDictionary<string, IOpenApiExample>? Examples { get; set; } = new Dictionary<string, IOpenApiExample>();
public IDictionary<string, IOpenApiExample>? Examples { get; set; }

/// <summary>
/// An object to hold reusable <see cref="IOpenApiRequestBody"/> Objects.
/// </summary>
public IDictionary<string, IOpenApiRequestBody>? RequestBodies { get; set; } =
new Dictionary<string, IOpenApiRequestBody>();
public IDictionary<string, IOpenApiRequestBody>? RequestBodies { get; set; }

/// <summary>
/// An object to hold reusable <see cref="IOpenApiHeader"/> Objects.
/// </summary>
public IDictionary<string, IOpenApiHeader>? Headers { get; set; } = new Dictionary<string, IOpenApiHeader>();
public IDictionary<string, IOpenApiHeader>? Headers { get; set; }

/// <summary>
/// An object to hold reusable <see cref="IOpenApiSecurityScheme"/> Objects.
/// </summary>
public IDictionary<string, IOpenApiSecurityScheme>? SecuritySchemes { get; set; } =
new Dictionary<string, IOpenApiSecurityScheme>();
public IDictionary<string, IOpenApiSecurityScheme>? SecuritySchemes { get; set; }

/// <summary>
/// An object to hold reusable <see cref="IOpenApiLink"/> Objects.
/// </summary>
public IDictionary<string, IOpenApiLink>? Links { get; set; } = new Dictionary<string, IOpenApiLink>();
public IDictionary<string, IOpenApiLink>? Links { get; set; }

/// <summary>
/// An object to hold reusable <see cref="OpenApiCallback"/> Objects.
/// </summary>
public IDictionary<string, IOpenApiCallback>? Callbacks { get; set; } = new Dictionary<string, IOpenApiCallback>();
public IDictionary<string, IOpenApiCallback>? Callbacks { get; set; }

/// <summary>
/// An object to hold reusable <see cref="IOpenApiPathItem"/> Object.
/// </summary>
public IDictionary<string, IOpenApiPathItem>? PathItems { get; set; } = new Dictionary<string, IOpenApiPathItem>();
public IDictionary<string, IOpenApiPathItem>? PathItems { get; set; }

/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <summary>
/// Parameter-less constructor
Expand Down Expand Up @@ -318,7 +315,7 @@ private void RenderComponents(IOpenApiWriter writer, Action<IOpenApiWriter, IOpe
{
var loops = writer.GetSettings().LoopDetector.Loops;
writer.WriteStartObject();
if (loops.TryGetValue(typeof(OpenApiSchema), out var schemas))
if (loops.TryGetValue(typeof(OpenApiSchema), out _))
{
writer.WriteOptionalMap(OpenApiConstants.Schemas, Schemas, callback);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiContact.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class OpenApiContact : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <summary>
/// Parameter-less constructor
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ public class OpenApiDiscriminator : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// An object to hold mappings between payload values and schema names or references.
/// </summary>
public IDictionary<string, OpenApiSchemaReference>? Mapping { get; set; } = new Dictionary<string, OpenApiSchemaReference>();
public IDictionary<string, OpenApiSchemaReference>? Mapping { get; set; }

/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <summary>
/// Parameter-less constructor
Expand Down
9 changes: 4 additions & 5 deletions src/Microsoft.OpenApi/Models/OpenApiDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void RegisterComponents()
/// <summary>
/// An array of Server Objects, which provide connectivity information to a target server.
/// </summary>
public IList<OpenApiServer>? Servers { get; set; } = new List<OpenApiServer>();
public IList<OpenApiServer>? Servers { get; set; } = [];

/// <summary>
/// REQUIRED. The available paths and operations for the API.
Expand All @@ -61,7 +61,7 @@ public void RegisterComponents()
/// A map of requests initiated other than by an API call, for example by an out of band registration.
/// The key name is a unique string to refer to each webhook, while the (optionally referenced) Path Item Object describes a request that may be initiated by the API provider and the expected responses
/// </summary>
public IDictionary<string, IOpenApiPathItem>? Webhooks { get; set; } = new Dictionary<string, IOpenApiPathItem>();
public IDictionary<string, IOpenApiPathItem>? Webhooks { get; set; }

/// <summary>
/// An element to hold various schemas for the specification.
Expand All @@ -71,8 +71,7 @@ public void RegisterComponents()
/// <summary>
/// A declaration of which security mechanisms can be used across the API.
/// </summary>
public IList<OpenApiSecurityRequirement>? Security { get; set; } =
new List<OpenApiSecurityRequirement>();
public IList<OpenApiSecurityRequirement>? Security { get; set; }

private HashSet<OpenApiTag>? _tags;
/// <summary>
Expand Down Expand Up @@ -104,7 +103,7 @@ public ISet<OpenApiTag>? Tags
/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <inheritdoc />
public IDictionary<string, object>? Metadata { get; set; }
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.OpenApi/Models/OpenApiEncoding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class OpenApiEncoding : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// A map allowing additional information to be provided as headers.
/// </summary>
public IDictionary<string, IOpenApiHeader>? Headers { get; set; } = new Dictionary<string, IOpenApiHeader>();
public IDictionary<string, IOpenApiHeader>? Headers { get; set; }

/// <summary>
/// Describes how a specific property value will be serialized depending on its type.
Expand All @@ -52,7 +52,7 @@ public class OpenApiEncoding : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <summary>
/// Parameter-less constructor
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.OpenApi/Models/OpenApiExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Microsoft.OpenApi.Models
/// <summary>
/// Example Object.
/// </summary>
public class OpenApiExample : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiExample
public class OpenApiExample : IOpenApiExtensible, IOpenApiExample
{
/// <inheritdoc/>
public string? Summary { get; set; }
Expand All @@ -28,7 +28,7 @@ public class OpenApiExample : IOpenApiReferenceable, IOpenApiExtensible, IOpenAp
public JsonNode? Value { get; set; }

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

/// <summary>
/// Parameter-less constructor
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiExternalDocs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class OpenApiExternalDocs : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <summary>
/// Parameter-less constructor
Expand Down
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi/Models/OpenApiHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ public class OpenApiHeader : IOpenApiHeader, IOpenApiExtensible
public JsonNode? Example { get; set; }

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

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

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

/// <summary>
/// Parameter-less constructor
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class OpenApiInfo : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <summary>
/// Parameter-less constructor
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiLicense.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class OpenApiLicense : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <summary>
/// Parameterless constructor
Expand Down
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi/Models/OpenApiLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Microsoft.OpenApi.Models
/// <summary>
/// Link Object.
/// </summary>
public class OpenApiLink : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiLink
public class OpenApiLink : IOpenApiExtensible, IOpenApiLink
{
/// <inheritdoc/>
public string? OperationRef { get; set; }
Expand All @@ -21,7 +21,7 @@ public class OpenApiLink : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiLi
public string? OperationId { get; set; }

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

/// <inheritdoc/>
public RuntimeExpressionAnyWrapper? RequestBody { get; set; }
Expand All @@ -33,7 +33,7 @@ public class OpenApiLink : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiLi
public OpenApiServer? Server { get; set; }

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

/// <summary>
/// Parameterless constructor
Expand Down
6 changes: 3 additions & 3 deletions src/Microsoft.OpenApi/Models/OpenApiMediaType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,20 @@ public class OpenApiMediaType : IOpenApiSerializable, IOpenApiExtensible
/// Examples of the media type.
/// Each example object SHOULD match the media type and specified schema if present.
/// </summary>
public IDictionary<string, IOpenApiExample>? Examples { get; set; } = new Dictionary<string, IOpenApiExample>();
public IDictionary<string, IOpenApiExample>? Examples { get; set; }

/// <summary>
/// A map between a property name and its encoding information.
/// The key, being the property name, MUST exist in the schema as a property.
/// The encoding object SHALL only apply to requestBody objects
/// when the media type is multipart or application/x-www-form-urlencoded.
/// </summary>
public IDictionary<string, OpenApiEncoding>? Encoding { get; set; } = new Dictionary<string, OpenApiEncoding>();
public IDictionary<string, OpenApiEncoding>? Encoding { get; set; }

/// <summary>
/// Serialize <see cref="OpenApiExternalDocs"/> to Open Api v3.0.
/// </summary>
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <summary>
/// Parameterless constructor
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.OpenApi/Models/OpenApiOAuthFlow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ public class OpenApiOAuthFlow : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// REQUIRED. A map between the scope name and a short description for it.
/// </summary>
public IDictionary<string, string>? Scopes { get; set; } = new Dictionary<string, string>();
public IDictionary<string, string>? Scopes { get; set; }

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

/// <summary>
/// Parameterless constructor
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiOAuthFlows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class OpenApiOAuthFlows : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <summary>
/// Parameterless constructor
Expand Down
10 changes: 5 additions & 5 deletions src/Microsoft.OpenApi/Models/OpenApiOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public ISet<OpenApiTagReference>? Tags
/// The list MUST NOT include duplicated parameters. A unique parameter is defined by a combination of a name and location.
/// The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object's components/parameters.
/// </summary>
public IList<IOpenApiParameter>? Parameters { get; set; } = [];
public IList<IOpenApiParameter>? Parameters { get; set; }

/// <summary>
/// The request body applicable for this operation.
Expand All @@ -96,7 +96,7 @@ public ISet<OpenApiTagReference>? Tags
/// The key value used to identify the callback object is an expression, evaluated at runtime,
/// that identifies a URL to use for the callback operation.
/// </summary>
public IDictionary<string, IOpenApiCallback>? Callbacks { get; set; } = new Dictionary<string, IOpenApiCallback>();
public IDictionary<string, IOpenApiCallback>? Callbacks { get; set; }

/// <summary>
/// Declares this operation to be deprecated. Consumers SHOULD refrain from usage of the declared operation.
Expand All @@ -110,19 +110,19 @@ public ISet<OpenApiTagReference>? Tags
/// This definition overrides any declared top-level security.
/// To remove a top-level security declaration, an empty array can be used.
/// </summary>
public IList<OpenApiSecurityRequirement>? Security { get; set; } = new List<OpenApiSecurityRequirement>();
public IList<OpenApiSecurityRequirement>? Security { get; set; }

/// <summary>
/// An alternative server array to service this operation.
/// If an alternative server object is specified at the Path Item Object or Root level,
/// it will be overridden by this value.
/// </summary>
public IList<OpenApiServer>? Servers { get; set; } = new List<OpenApiServer>();
public IList<OpenApiServer>? Servers { get; set; }

/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
public IDictionary<string, IOpenApiExtension>? Extensions { get; set; }

/// <inheritdoc />
public IDictionary<string, object>? Metadata { get; set; }
Expand Down
Loading