Skip to content

Commit 9af6f30

Browse files
committed
fix: shallow copy for parameter link path item and request body
Signed-off-by: Vincent Biret <[email protected]>
1 parent 2a42c36 commit 9af6f30

15 files changed

+119
-40
lines changed

src/Microsoft.OpenApi/Models/Interfaces/IOpenApiLink.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
77
/// Defines the base properties for the link object.
88
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
99
/// </summary>
10-
public interface IOpenApiLink : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
10+
public interface IOpenApiLink : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiLink>
1111
{
1212
/// <summary>
1313
/// A relative or absolute reference to an OAS operation.

src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
88
/// Defines the base properties for the parameter object.
99
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
1010
/// </summary>
11-
public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
11+
public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiParameter>
1212
{
1313
/// <summary>
1414
/// REQUIRED. The name of the parameter. Parameter names are case sensitive.

src/Microsoft.OpenApi/Models/Interfaces/IOpenApiPathItem.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
88
/// Defines the base properties for the path item object.
99
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
1010
/// </summary>
11-
public interface IOpenApiPathItem : IOpenApiDescribedElement, IOpenApiSummarizedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
11+
public interface IOpenApiPathItem : IOpenApiDescribedElement, IOpenApiSummarizedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiPathItem>
1212
{
1313
/// <summary>
1414
/// Gets the definition of operations on this path.

src/Microsoft.OpenApi/Models/Interfaces/IOpenApiRequestBody.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Microsoft.OpenApi.Models.Interfaces;
88
/// Defines the base properties for the request body object.
99
/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking.
1010
/// </summary>
11-
public interface IOpenApiRequestBody : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible
11+
public interface IOpenApiRequestBody : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible, IShallowCopyable<IOpenApiRequestBody>
1212
{
1313
/// <summary>
1414
/// Determines if the request body is required in the request. Defaults to false.

src/Microsoft.OpenApi/Models/OpenApiLink.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public OpenApiLink() { }
4343
/// <summary>
4444
/// Initializes a copy of an <see cref="OpenApiLink"/> object
4545
/// </summary>
46-
public OpenApiLink(IOpenApiLink link)
46+
internal OpenApiLink(IOpenApiLink link)
4747
{
4848
Utils.CheckArgumentNull(link);
4949
OperationRef = link.OperationRef ?? OperationRef;
@@ -102,5 +102,11 @@ public void SerializeAsV2(IOpenApiWriter writer)
102102
{
103103
// Link object does not exist in V2.
104104
}
105+
106+
/// <inheritdoc/>
107+
public IOpenApiLink CreateShallowCopy()
108+
{
109+
return new OpenApiLink(this);
110+
}
105111
}
106112
}

src/Microsoft.OpenApi/Models/OpenApiOperation.cs

+16-15
Original file line numberDiff line numberDiff line change
@@ -120,22 +120,23 @@ public OpenApiOperation() { }
120120
/// <summary>
121121
/// Initializes a copy of an <see cref="OpenApiOperation"/> object
122122
/// </summary>
123-
public OpenApiOperation(OpenApiOperation? operation)
123+
public OpenApiOperation(OpenApiOperation operation)
124124
{
125-
Tags = operation?.Tags != null ? new List<OpenApiTagReference>(operation.Tags) : null;
126-
Summary = operation?.Summary ?? Summary;
127-
Description = operation?.Description ?? Description;
128-
ExternalDocs = operation?.ExternalDocs != null ? new(operation?.ExternalDocs) : null;
129-
OperationId = operation?.OperationId ?? OperationId;
130-
Parameters = operation?.Parameters != null ? new List<IOpenApiParameter>(operation.Parameters) : null;
131-
RequestBody = operation?.RequestBody != null ? new OpenApiRequestBody(operation?.RequestBody) : null;
132-
Responses = operation?.Responses != null ? new(operation?.Responses) : null;
133-
Callbacks = operation?.Callbacks != null ? new Dictionary<string, IOpenApiCallback>(operation.Callbacks) : null;
134-
Deprecated = operation?.Deprecated ?? Deprecated;
135-
Security = operation?.Security != null ? new List<OpenApiSecurityRequirement>(operation.Security) : null;
136-
Servers = operation?.Servers != null ? new List<OpenApiServer>(operation.Servers) : null;
137-
Extensions = operation?.Extensions != null ? new Dictionary<string, IOpenApiExtension>(operation.Extensions) : null;
138-
Annotations = operation?.Annotations != null ? new Dictionary<string, object>(operation.Annotations) : null;
125+
Utils.CheckArgumentNull(operation);
126+
Tags = operation.Tags != null ? new List<OpenApiTagReference>(operation.Tags) : null;
127+
Summary = operation.Summary ?? Summary;
128+
Description = operation.Description ?? Description;
129+
ExternalDocs = operation.ExternalDocs != null ? new(operation.ExternalDocs) : null;
130+
OperationId = operation.OperationId ?? OperationId;
131+
Parameters = operation.Parameters != null ? new List<IOpenApiParameter>(operation.Parameters) : null;
132+
RequestBody = operation.RequestBody?.CreateShallowCopy();
133+
Responses = operation.Responses != null ? new(operation.Responses) : null;
134+
Callbacks = operation.Callbacks != null ? new Dictionary<string, IOpenApiCallback>(operation.Callbacks) : null;
135+
Deprecated = operation.Deprecated;
136+
Security = operation.Security != null ? new List<OpenApiSecurityRequirement>(operation.Security) : null;
137+
Servers = operation.Servers != null ? new List<OpenApiServer>(operation.Servers) : null;
138+
Extensions = operation.Extensions != null ? new Dictionary<string, IOpenApiExtension>(operation.Extensions) : null;
139+
Annotations = operation.Annotations != null ? new Dictionary<string, object>(operation.Annotations) : null;
139140
}
140141

141142
/// <summary>

src/Microsoft.OpenApi/Models/OpenApiParameter.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public OpenApiParameter() { }
8080
/// <summary>
8181
/// Initializes a clone instance of <see cref="OpenApiParameter"/> object
8282
/// </summary>
83-
public OpenApiParameter(IOpenApiParameter parameter)
83+
internal OpenApiParameter(IOpenApiParameter parameter)
8484
{
8585
Utils.CheckArgumentNull(parameter);
8686
Name = parameter.Name ?? Name;
@@ -302,6 +302,12 @@ public void SerializeAsV2(IOpenApiWriter writer)
302302
_ => (ParameterStyle?)ParameterStyle.Simple,
303303
};
304304
}
305+
306+
/// <inheritdoc/>
307+
public IOpenApiParameter CreateShallowCopy()
308+
{
309+
return new OpenApiParameter(this);
310+
}
305311
}
306312

307313
/// <summary>

src/Microsoft.OpenApi/Models/OpenApiPathItem.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public OpenApiPathItem() { }
5252
/// <summary>
5353
/// Initializes a clone of an <see cref="OpenApiPathItem"/> object
5454
/// </summary>
55-
public OpenApiPathItem(IOpenApiPathItem pathItem)
55+
internal OpenApiPathItem(IOpenApiPathItem pathItem)
5656
{
5757
Utils.CheckArgumentNull(pathItem);
5858
Summary = pathItem?.Summary ?? Summary;
@@ -151,5 +151,11 @@ internal virtual void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersio
151151

152152
writer.WriteEndObject();
153153
}
154+
155+
/// <inheritdoc/>
156+
public IOpenApiPathItem CreateShallowCopy()
157+
{
158+
return new OpenApiPathItem(this);
159+
}
154160
}
155161
}

src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public OpenApiRequestBody() { }
3838
/// <summary>
3939
/// Initializes a copy instance of an <see cref="IOpenApiRequestBody"/> object
4040
/// </summary>
41-
public OpenApiRequestBody(IOpenApiRequestBody requestBody)
41+
internal OpenApiRequestBody(IOpenApiRequestBody requestBody)
4242
{
4343
Utils.CheckArgumentNull(requestBody);
4444
Description = requestBody?.Description ?? Description;
@@ -150,5 +150,11 @@ public IEnumerable<IOpenApiParameter> ConvertToFormDataParameters(IOpenApiWriter
150150
};
151151
}
152152
}
153+
154+
/// <inheritdoc/>
155+
public IOpenApiRequestBody CreateShallowCopy()
156+
{
157+
return new OpenApiRequestBody(this);
158+
}
153159
}
154160
}

src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs

+6
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,11 @@ public override IOpenApiLink CopyReferenceAsTargetElementWithOverrides(IOpenApiL
8080
{
8181
return source is OpenApiLink ? new OpenApiLink(this) : source;
8282
}
83+
84+
/// <inheritdoc/>
85+
public IOpenApiLink CreateShallowCopy()
86+
{
87+
return new OpenApiLinkReference(this);
88+
}
8389
}
8490
}

src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs

+6
Original file line numberDiff line numberDiff line change
@@ -96,5 +96,11 @@ public override IOpenApiParameter CopyReferenceAsTargetElementWithOverrides(IOpe
9696
{
9797
return source is OpenApiParameter ? new OpenApiParameter(this) : source;
9898
}
99+
100+
/// <inheritdoc/>
101+
public IOpenApiParameter CreateShallowCopy()
102+
{
103+
return new OpenApiParameterReference(this);
104+
}
99105
}
100106
}

src/Microsoft.OpenApi/Models/References/OpenApiPathItemReference.cs

+15
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ public OpenApiPathItemReference(string referenceId, OpenApiDocument hostDocument
2828
{
2929
}
3030

31+
/// <summary>
32+
/// Copy constructor
33+
/// </summary>
34+
/// <param name="pathItem">The reference to copy</param>
35+
private OpenApiPathItemReference(OpenApiPathItemReference pathItem):base(pathItem)
36+
{
37+
38+
}
39+
3140
internal OpenApiPathItemReference(OpenApiPathItem target, string referenceId):base(target, referenceId, ReferenceType.PathItem)
3241
{
3342
}
@@ -76,6 +85,12 @@ public override IOpenApiPathItem CopyReferenceAsTargetElementWithOverrides(IOpen
7685
return source is OpenApiPathItem ? new OpenApiPathItem(this) : source;
7786
}
7887

88+
/// <inheritdoc/>
89+
public IOpenApiPathItem CreateShallowCopy()
90+
{
91+
return new OpenApiPathItemReference(this);
92+
}
93+
7994
/// <inheritdoc/>
8095
public override void SerializeAsV2(IOpenApiWriter writer)
8196
{

src/Microsoft.OpenApi/Models/References/OpenApiRequestBodyReference.cs

+14
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ public class OpenApiRequestBodyReference : BaseOpenApiReferenceHolder<OpenApiReq
2727
/// </param>
2828
public OpenApiRequestBodyReference(string referenceId, OpenApiDocument hostDocument, string externalResource = null):base(referenceId, hostDocument, ReferenceType.RequestBody, externalResource)
2929
{
30+
}
31+
/// <summary>
32+
/// Copy constructor
33+
/// </summary>
34+
/// <param name="openApiRequestBodyReference">The reference to copy</param>
35+
private OpenApiRequestBodyReference(OpenApiRequestBodyReference openApiRequestBodyReference):base(openApiRequestBodyReference)
36+
{
37+
3038
}
3139
internal OpenApiRequestBodyReference(OpenApiRequestBody target, string referenceId):base(target, referenceId, ReferenceType.RequestBody)
3240
{
@@ -89,5 +97,11 @@ public IEnumerable<IOpenApiParameter> ConvertToFormDataParameters(IOpenApiWriter
8997

9098
return Content.First().Value.Schema.Properties.Select(x => new OpenApiParameterReference(x.Key, Reference.HostDocument));
9199
}
100+
101+
/// <inheritdoc/>
102+
public IOpenApiRequestBody CreateShallowCopy()
103+
{
104+
return new OpenApiRequestBodyReference(this);
105+
}
92106
}
93107
}

src/Microsoft.OpenApi/Utils.cs

+9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license.
33

44
using System;
5+
using System.Diagnostics.CodeAnalysis;
56
using System.Runtime.CompilerServices;
67

78
namespace Microsoft.OpenApi
@@ -19,7 +20,11 @@ internal static class Utils
1920
/// <param name="parameterName">The input parameter name.</param>
2021
/// <returns>The input value.</returns>
2122
internal static T CheckArgumentNull<T>(
23+
#if NET5_0_OR_GREATER
24+
[NotNull] T value,
25+
#else
2226
T value,
27+
#endif
2328
[CallerArgumentExpression(nameof(value))] string parameterName = "")
2429
{
2530
return value ?? throw new ArgumentNullException(parameterName, $"Value cannot be null: {parameterName}");
@@ -32,7 +37,11 @@ internal static T CheckArgumentNull<T>(
3237
/// <param name="parameterName">The input parameter name.</param>
3338
/// <returns>The input value.</returns>
3439
internal static string CheckArgumentNullOrEmpty(
40+
#if NET5_0_OR_GREATER
41+
[NotNull] string value,
42+
#else
3543
string value,
44+
#endif
3645
[CallerArgumentExpression(nameof(value))] string parameterName = "")
3746
{
3847
return string.IsNullOrWhiteSpace(value) ? throw new ArgumentNullException(parameterName, $"Value cannot be null or empty: {parameterName}") : value;

0 commit comments

Comments
 (0)