Skip to content

Commit b69922e

Browse files
authored
Merge branch 'dev' into fix/tag-references
2 parents 9db6e2d + 1394da7 commit b69922e

22 files changed

+364
-267
lines changed
Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,15 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4-
using System.Text.Json;
54
using System.Text.Json.Nodes;
6-
using System.Text.Json.Serialization;
7-
using Microsoft.OpenApi.Any;
85

96
namespace Microsoft.OpenApi.Helpers
107
{
118
internal static class JsonNodeCloneHelper
129
{
13-
private static readonly JsonSerializerOptions options = new()
14-
{
15-
ReferenceHandler = ReferenceHandler.IgnoreCycles
16-
};
17-
1810
internal static JsonNode Clone(JsonNode value)
1911
{
20-
var jsonString = Serialize(value);
21-
if (string.IsNullOrEmpty(jsonString))
22-
{
23-
return null;
24-
}
25-
26-
var result = JsonSerializer.Deserialize<JsonNode>(jsonString, options);
27-
return result;
28-
}
29-
30-
private static string Serialize(object obj)
31-
{
32-
if (obj == null)
33-
{
34-
return null;
35-
}
36-
var result = JsonSerializer.Serialize(obj, options);
37-
return result;
12+
return value.DeepClone();
3813
}
3914
}
4015
}

src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceable.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the MIT license.
33

44
using Microsoft.OpenApi.Models;
5-
using Microsoft.OpenApi.Writers;
65

76
namespace Microsoft.OpenApi.Interfaces
87
{

src/Microsoft.OpenApi/Interfaces/IStreamLoader.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the MIT license.
33

44
using System;
5-
using System.ComponentModel;
65
using System.IO;
76
using System.Threading.Tasks;
87
using Microsoft.OpenApi.Models;
@@ -20,14 +19,5 @@ public interface IStreamLoader
2019
/// <param name="uri">Identifier of some source of an OpenAPI Description</param>
2120
/// <returns>A data object that can be processed by a reader to generate an <see cref="OpenApiDocument"/></returns>
2221
Task<Stream> LoadAsync(Uri uri);
23-
24-
/// <summary>
25-
/// Use Uri to locate data and convert into an input object.
26-
/// </summary>
27-
/// <param name="uri"></param>
28-
/// <returns></returns>
29-
[Obsolete("Use the Async overload")]
30-
[EditorBrowsable(EditorBrowsableState.Never)]
31-
Stream Load(Uri uri);
3222
}
3323
}

src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumValuesDescriptionExtension.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,9 @@ public class OpenApiEnumValuesDescriptionExtension : IOpenApiExtension
4141
public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
4242
{
4343
if (writer is null) throw new ArgumentNullException(nameof(writer));
44-
if (specVersion is OpenApiSpecVersion.OpenApi2_0 or OpenApiSpecVersion.OpenApi3_0 &&
45-
!string.IsNullOrEmpty(EnumName) &&
44+
if (!string.IsNullOrEmpty(EnumName) &&
4645
ValuesDescriptions.Any())
47-
{ // when we upgrade to 3.1, we don't need to write this extension as JSON schema will support writing enum values
46+
{
4847
writer.WriteStartObject();
4948
writer.WriteProperty(nameof(Name).ToFirstCharacterLowerCase(), EnumName);
5049
writer.WriteProperty("modelAsString", false);

src/Microsoft.OpenApi/Models/OpenApiComponents.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
using System;
55
using System.Collections.Generic;
6-
using System.Linq;
76
using Microsoft.OpenApi.Interfaces;
87
using Microsoft.OpenApi.Models.References;
98
using Microsoft.OpenApi.Writers;

src/Microsoft.OpenApi/Models/OpenApiDocument.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,67 @@ public static ReadResult Parse(string input,
572572
{
573573
return OpenApiModelFactory.Parse(input, format, settings);
574574
}
575+
/// <summary>
576+
/// Adds a component to the components object of the current document and registers it to the underlying workspace.
577+
/// </summary>
578+
/// <param name="componentToRegister">The component to add</param>
579+
/// <param name="id">The id for the component</param>
580+
/// <typeparam name="T">The type of the component</typeparam>
581+
/// <returns>Whether the component was added to the components.</returns>
582+
/// <exception cref="ArgumentNullException">Thrown when the component is null.</exception>
583+
/// <exception cref="ArgumentException">Thrown when the id is null or empty.</exception>
584+
public bool AddComponent<T>(string id, T componentToRegister)
585+
{
586+
Utils.CheckArgumentNull(componentToRegister);
587+
Utils.CheckArgumentNullOrEmpty(id);
588+
Components ??= new();
589+
switch (componentToRegister)
590+
{
591+
case OpenApiSchema openApiSchema:
592+
Components.Schemas ??= new Dictionary<string, OpenApiSchema>();
593+
Components.Schemas.Add(id, openApiSchema);
594+
break;
595+
case OpenApiParameter openApiParameter:
596+
Components.Parameters ??= new Dictionary<string, OpenApiParameter>();
597+
Components.Parameters.Add(id, openApiParameter);
598+
break;
599+
case OpenApiResponse openApiResponse:
600+
Components.Responses ??= new Dictionary<string, OpenApiResponse>();
601+
Components.Responses.Add(id, openApiResponse);
602+
break;
603+
case OpenApiRequestBody openApiRequestBody:
604+
Components.RequestBodies ??= new Dictionary<string, OpenApiRequestBody>();
605+
Components.RequestBodies.Add(id, openApiRequestBody);
606+
break;
607+
case OpenApiLink openApiLink:
608+
Components.Links ??= new Dictionary<string, OpenApiLink>();
609+
Components.Links.Add(id, openApiLink);
610+
break;
611+
case OpenApiCallback openApiCallback:
612+
Components.Callbacks ??= new Dictionary<string, OpenApiCallback>();
613+
Components.Callbacks.Add(id, openApiCallback);
614+
break;
615+
case OpenApiPathItem openApiPathItem:
616+
Components.PathItems ??= new Dictionary<string, OpenApiPathItem>();
617+
Components.PathItems.Add(id, openApiPathItem);
618+
break;
619+
case OpenApiExample openApiExample:
620+
Components.Examples ??= new Dictionary<string, OpenApiExample>();
621+
Components.Examples.Add(id, openApiExample);
622+
break;
623+
case OpenApiHeader openApiHeader:
624+
Components.Headers ??= new Dictionary<string, OpenApiHeader>();
625+
Components.Headers.Add(id, openApiHeader);
626+
break;
627+
case OpenApiSecurityScheme openApiSecurityScheme:
628+
Components.SecuritySchemes ??= new Dictionary<string, OpenApiSecurityScheme>();
629+
Components.SecuritySchemes.Add(id, openApiSecurityScheme);
630+
break;
631+
default:
632+
throw new ArgumentException($"Component type {componentToRegister!.GetType().Name} is not supported.");
633+
}
634+
return Workspace?.RegisterComponentForDocument(this, componentToRegister, id) ?? false;
635+
}
575636
}
576637

577638
internal class FindSchemaReferences : OpenApiVisitorBase

src/Microsoft.OpenApi/Models/OpenApiOperation.cs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -237,18 +237,18 @@ public void SerializeAsV2(IOpenApiWriter writer)
237237
List<OpenApiParameter> parameters;
238238
if (Parameters == null)
239239
{
240-
parameters = new();
240+
parameters = [];
241241
}
242242
else
243243
{
244-
parameters = new(Parameters);
244+
parameters = [.. Parameters];
245245
}
246246

247247
if (RequestBody != null)
248248
{
249249
// consumes
250-
var consumes = RequestBody.Content.Keys.Distinct().ToList();
251-
if (consumes.Any())
250+
var consumes = new HashSet<string>(RequestBody.Content?.Keys.Distinct(StringComparer.OrdinalIgnoreCase) ?? [], StringComparer.OrdinalIgnoreCase);
251+
if (consumes.Count > 0)
252252
{
253253
// This is form data. We need to split the request body into multiple parameters.
254254
if (consumes.Contains("application/x-www-form-urlencoded") ||
@@ -261,19 +261,13 @@ public void SerializeAsV2(IOpenApiWriter writer)
261261
parameters.Add(RequestBody.ConvertToBodyParameter());
262262
}
263263
}
264-
else if (RequestBody.Reference != null)
264+
else if (RequestBody.Reference != null && RequestBody.Reference.HostDocument is {} hostDocument)
265265
{
266-
var hostDocument = RequestBody.Reference.HostDocument;
267266
parameters.Add(
268267
new OpenApiParameterReference(RequestBody.Reference.Id, hostDocument));
269-
270-
if (hostDocument != null)
271-
{
272-
consumes = RequestBody.Content.Keys.Distinct().ToList();
273-
}
274268
}
275269

276-
if (consumes.Any())
270+
if (consumes.Count > 0)
277271
{
278272
writer.WritePropertyName(OpenApiConstants.Consumes);
279273
writer.WriteStartArray();
@@ -294,10 +288,10 @@ public void SerializeAsV2(IOpenApiWriter writer)
294288
Responses
295289
.Where(static r => r.Value.Reference is {HostDocument: not null})
296290
.SelectMany(static r => r.Value.Content?.Keys))
297-
.Distinct()
298-
.ToList();
291+
.Distinct(StringComparer.OrdinalIgnoreCase)
292+
.ToArray();
299293

300-
if (produces.Any())
294+
if (produces.Length > 0)
301295
{
302296
// produces
303297
writer.WritePropertyName(OpenApiConstants.Produces);

src/Microsoft.OpenApi/Models/OpenApiSchema.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ internal void WriteAsItemsProperties(IOpenApiWriter writer)
650650
/// <param name="writer">The open api writer.</param>
651651
/// <param name="parentRequiredProperties">The list of required properties in parent schema.</param>
652652
/// <param name="propertyName">The property name that will be serialized.</param>
653-
internal void SerializeAsV2(
653+
internal virtual void SerializeAsV2(
654654
IOpenApiWriter writer,
655655
ISet<string> parentRequiredProperties,
656656
string propertyName)

0 commit comments

Comments
 (0)