Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix/references cleanup #2111

Merged
merged 14 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 4 additions & 13 deletions src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceHolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,14 @@ namespace Microsoft.OpenApi.Interfaces
/// <summary>
/// A generic interface for OpenApiReferenceable objects that have a target.
/// </summary>
/// <typeparam name="T">Type of the target being referenced</typeparam>
public interface IOpenApiReferenceHolder<out T> : IOpenApiReferenceHolder where T : IOpenApiReferenceable
/// <typeparam name="T">The type of the target being referenced</typeparam>
/// <typeparam name="V">The type of the interface implemented by both the target and the reference type</typeparam>
public interface IOpenApiReferenceHolder<out T, V> : IOpenApiReferenceHolder where T : IOpenApiReferenceable, V
{
/// <summary>
/// Gets the resolved target object.
/// </summary>
T Target { get; }
}
/// <summary>
/// A generic interface for OpenApiReferenceable objects that have a target.
/// </summary>
/// <typeparam name="T">The type of the target being referenced</typeparam>
/// <typeparam name="V">The type of the interface implemented by both the target and the reference type</typeparam>
public interface IOpenApiReferenceHolder<out T, V> : IOpenApiReferenceHolder<T> where T : IOpenApiReferenceable, V
{
//TODO merge this interface with the previous once all implementations are updated
/// <summary>
/// Copy the reference as a target element with overrides.
/// </summary>
Expand All @@ -37,8 +29,7 @@ public interface IOpenApiReferenceHolder : IOpenApiSerializable
/// <summary>
/// Indicates if object is populated with data or is just a reference to the data
/// </summary>
bool UnresolvedReference { get; set; }
//TODO the UnresolvedReference property setter should be removed and a default implementation that checks whether the target is null for the getter should be provided instead
bool UnresolvedReference { get; }

/// <summary>
/// Reference object.
Expand Down
12 changes: 12 additions & 0 deletions src/Microsoft.OpenApi/Interfaces/IShallowCopyable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Microsoft.OpenApi.Interfaces;
/// <summary>
/// Interface for shallow copyable objects.
/// </summary>
/// <typeparam name="T">The type of the resulting object</typeparam>
public interface IShallowCopyable<out T>
{
/// <summary>
/// Create a shallow copy of the current instance.
/// </summary>
T CreateShallowCopy();
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
/// Defines the base properties for the callback object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiCallback : IOpenApiSerializable, IOpenApiReadOnlyExtensible
public interface IOpenApiCallback : IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiCallback>
{
/// <summary>
/// A Path Item Object used to define a callback request and expected responses.
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/Interfaces/IOpenApiExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
/// Defines the base properties for the example object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiExample : IOpenApiDescribedElement, IOpenApiSummarizedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
public interface IOpenApiExample : IOpenApiDescribedElement, IOpenApiSummarizedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiExample>
{
/// <summary>
/// Embedded literal example. The value field and externalValue field are mutually
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/Interfaces/IOpenApiHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
/// Defines the base properties for the headers object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiHeader : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
public interface IOpenApiHeader : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiHeader>
{
/// <summary>
/// Determines whether this header is mandatory.
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/Interfaces/IOpenApiLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
/// Defines the base properties for the link object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiLink : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
public interface IOpenApiLink : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiLink>
{
/// <summary>
/// A relative or absolute reference to an OAS operation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
/// Defines the base properties for the parameter object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiParameter>
{
/// <summary>
/// REQUIRED. The name of the parameter. Parameter names are case sensitive.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
/// Defines the base properties for the path item object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiPathItem : IOpenApiDescribedElement, IOpenApiSummarizedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
public interface IOpenApiPathItem : IOpenApiDescribedElement, IOpenApiSummarizedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiPathItem>
{
/// <summary>
/// Gets the definition of operations on this path.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
/// Defines the base properties for the request body object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiRequestBody : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
public interface IOpenApiRequestBody : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiRequestBody>
{
/// <summary>
/// Determines if the request body is required in the request. Defaults to false.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
/// Defines the base properties for the response object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiResponse : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
public interface IOpenApiResponse : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiResponse>
{
/// <summary>
/// Maps a header name to its definition.
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
/// Defines the base properties for the schema object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiSchema>
{

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
/// Defines the base properties for the security scheme object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiSecurityScheme : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
public interface IOpenApiSecurityScheme : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiSecurityScheme>
{
/// <summary>
/// REQUIRED. The type of the security scheme. Valid values are "apiKey", "http", "oauth2", "openIdConnect".
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/Interfaces/IOpenApiTag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
/// Defines the base properties for the path item object.
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
/// </summary>
public interface IOpenApiTag : IOpenApiSerializable, IOpenApiReadOnlyExtensible, IOpenApiReadOnlyDescribedElement
public interface IOpenApiTag : IOpenApiSerializable, IOpenApiReadOnlyExtensible, IOpenApiReadOnlyDescribedElement, IShallowCopyable<IOpenApiTag>
{
/// <summary>
/// The name of the tag.
Expand Down
9 changes: 8 additions & 1 deletion src/Microsoft.OpenApi/Models/OpenApiCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ public OpenApiCallback() { }
/// <summary>
/// Initializes a copy of an <see cref="OpenApiCallback"/> object
/// </summary>
public OpenApiCallback(IOpenApiCallback callback)
internal OpenApiCallback(IOpenApiCallback callback)
{
Utils.CheckArgumentNull(callback);
PathItems = callback?.PathItems != null ? new(callback?.PathItems) : null;
Extensions = callback?.Extensions != null ? new Dictionary<string, IOpenApiExtension>(callback.Extensions) : null;
}
Expand Down Expand Up @@ -98,5 +99,11 @@ public void SerializeAsV2(IOpenApiWriter writer)
{
// Callback object does not exist in V2.
}

/// <inheritdoc/>
public IOpenApiCallback CreateShallowCopy()
{
return new OpenApiCallback(this);
}
}
}
20 changes: 10 additions & 10 deletions src/Microsoft.OpenApi/Models/OpenApiDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -587,43 +587,43 @@ public bool AddComponent<T>(string id, T componentToRegister)
Components ??= new();
switch (componentToRegister)
{
case OpenApiSchema openApiSchema:
case IOpenApiSchema openApiSchema:
Components.Schemas ??= new Dictionary<string, IOpenApiSchema>();
Components.Schemas.Add(id, openApiSchema);
break;
case OpenApiParameter openApiParameter:
case IOpenApiParameter openApiParameter:
Components.Parameters ??= new Dictionary<string, IOpenApiParameter>();
Components.Parameters.Add(id, openApiParameter);
break;
case OpenApiResponse openApiResponse:
case IOpenApiResponse openApiResponse:
Components.Responses ??= new Dictionary<string, IOpenApiResponse>();
Components.Responses.Add(id, openApiResponse);
break;
case OpenApiRequestBody openApiRequestBody:
case IOpenApiRequestBody openApiRequestBody:
Components.RequestBodies ??= new Dictionary<string, IOpenApiRequestBody>();
Components.RequestBodies.Add(id, openApiRequestBody);
break;
case OpenApiLink openApiLink:
case IOpenApiLink openApiLink:
Components.Links ??= new Dictionary<string, IOpenApiLink>();
Components.Links.Add(id, openApiLink);
break;
case OpenApiCallback openApiCallback:
case IOpenApiCallback openApiCallback:
Components.Callbacks ??= new Dictionary<string, IOpenApiCallback>();
Components.Callbacks.Add(id, openApiCallback);
break;
case OpenApiPathItem openApiPathItem:
case IOpenApiPathItem openApiPathItem:
Components.PathItems ??= new Dictionary<string, IOpenApiPathItem>();
Components.PathItems.Add(id, openApiPathItem);
break;
case OpenApiExample openApiExample:
case IOpenApiExample openApiExample:
Components.Examples ??= new Dictionary<string, IOpenApiExample>();
Components.Examples.Add(id, openApiExample);
break;
case OpenApiHeader openApiHeader:
case IOpenApiHeader openApiHeader:
Components.Headers ??= new Dictionary<string, IOpenApiHeader>();
Components.Headers.Add(id, openApiHeader);
break;
case OpenApiSecurityScheme openApiSecurityScheme:
case IOpenApiSecurityScheme openApiSecurityScheme:
Components.SecuritySchemes ??= new Dictionary<string, IOpenApiSecurityScheme>();
Components.SecuritySchemes.Add(id, openApiSecurityScheme);
break;
Expand Down
8 changes: 7 additions & 1 deletion src/Microsoft.OpenApi/Models/OpenApiExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public OpenApiExample() { }
/// Initializes a copy of <see cref="OpenApiExample"/> object
/// </summary>
/// <param name="example">The <see cref="IOpenApiExample"/> object</param>
public OpenApiExample(IOpenApiExample example)
internal OpenApiExample(IOpenApiExample example)
{
Utils.CheckArgumentNull(example);
Summary = example.Summary ?? Summary;
Expand Down Expand Up @@ -90,5 +90,11 @@ public void SerializeAsV2(IOpenApiWriter writer)
{
SerializeInternal(writer, OpenApiSpecVersion.OpenApi2_0);
}

/// <inheritdoc/>
public IOpenApiExample CreateShallowCopy()
{
return new OpenApiExample(this);
}
}
}
33 changes: 20 additions & 13 deletions src/Microsoft.OpenApi/Models/OpenApiHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,21 @@ public OpenApiHeader() { }
/// <summary>
/// Initializes a copy of an <see cref="OpenApiHeader"/> object
/// </summary>
public OpenApiHeader(IOpenApiHeader header)
internal OpenApiHeader(IOpenApiHeader header)
{
Description = header?.Description ?? Description;
Required = header?.Required ?? Required;
Deprecated = header?.Deprecated ?? Deprecated;
AllowEmptyValue = header?.AllowEmptyValue ?? AllowEmptyValue;
Style = header?.Style ?? Style;
Explode = header?.Explode ?? Explode;
AllowReserved = header?.AllowReserved ?? AllowReserved;
Schema = header?.Schema != null ? new OpenApiSchema(header.Schema) : null;
Example = header?.Example != null ? JsonNodeCloneHelper.Clone(header.Example) : null;
Examples = header?.Examples != null ? new Dictionary<string, IOpenApiExample>(header.Examples) : null;
Content = header?.Content != null ? new Dictionary<string, OpenApiMediaType>(header.Content) : null;
Extensions = header?.Extensions != null ? new Dictionary<string, IOpenApiExtension>(header.Extensions) : null;
Utils.CheckArgumentNull(header);
Description = header.Description ?? Description;
Required = header.Required;
Deprecated = header.Deprecated;
AllowEmptyValue = header.AllowEmptyValue;
Style = header.Style ?? Style;
Explode = header.Explode;
AllowReserved = header.AllowReserved;
Schema = header.Schema.CreateShallowCopy();
Example = header.Example != null ? JsonNodeCloneHelper.Clone(header.Example) : null;
Examples = header.Examples != null ? new Dictionary<string, IOpenApiExample>(header.Examples) : null;
Content = header.Content != null ? new Dictionary<string, OpenApiMediaType>(header.Content) : null;
Extensions = header.Extensions != null ? new Dictionary<string, IOpenApiExtension>(header.Extensions) : null;
}

/// <summary>
Expand Down Expand Up @@ -187,5 +188,11 @@ public void SerializeAsV2(IOpenApiWriter writer)

writer.WriteEndObject();
}

/// <inheritdoc/>
public IOpenApiHeader CreateShallowCopy()
{
return new OpenApiHeader(this);
}
}
}
8 changes: 7 additions & 1 deletion src/Microsoft.OpenApi/Models/OpenApiLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public OpenApiLink() { }
/// <summary>
/// Initializes a copy of an <see cref="OpenApiLink"/> object
/// </summary>
public OpenApiLink(IOpenApiLink link)
internal OpenApiLink(IOpenApiLink link)
{
Utils.CheckArgumentNull(link);
OperationRef = link.OperationRef ?? OperationRef;
Expand Down Expand Up @@ -102,5 +102,11 @@ public void SerializeAsV2(IOpenApiWriter writer)
{
// Link object does not exist in V2.
}

/// <inheritdoc/>
public IOpenApiLink CreateShallowCopy()
{
return new OpenApiLink(this);
}
}
}
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiMediaType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public OpenApiMediaType() { }
/// </summary>
public OpenApiMediaType(OpenApiMediaType? mediaType)
{
Schema = mediaType?.Schema != null ? new OpenApiSchema(mediaType.Schema) : null;
Schema = mediaType?.Schema?.CreateShallowCopy();
Example = mediaType?.Example != null ? JsonNodeCloneHelper.Clone(mediaType.Example) : null;
Examples = mediaType?.Examples != null ? new Dictionary<string, IOpenApiExample>(mediaType.Examples) : null;
Encoding = mediaType?.Encoding != null ? new Dictionary<string, OpenApiEncoding>(mediaType.Encoding) : null;
Expand Down
Loading
Loading