From 3207fb6a78d3f65edcf78ac8c82f174bf043bc91 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 25 May 2026 19:45:04 -0400 Subject: [PATCH 1/4] feat(reader): remove ParseNode infrastructure Refactor OpenAPI parsing to use System.Text.Json JsonNode APIs directly with explicit ParsingContext propagation, replacing the ParseNode wrapper hierarchy. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Interfaces/IOpenApiVersionService.cs | 19 +- .../Models/BaseOpenApiReference.cs | 7 +- .../Models/JsonSchemaReference.cs | 2 +- .../Reader/BaseOpenApiVersionService.cs | 21 +- .../Reader/JsonNodeHelper.cs | 282 +++++++++++++++++- .../Reader/ParseNodes/FixedFieldMap.cs | 3 +- .../Reader/ParseNodes/ListNode.cs | 76 ----- .../Reader/ParseNodes/MapNode.cs | 204 ------------- .../Reader/ParseNodes/ParseNode.cs | 92 ------ .../Reader/ParseNodes/PatternFieldMap.cs | 3 +- .../Reader/ParseNodes/PropertyNode.cs | 95 ------ .../Reader/ParseNodes/RootNode.cs | 37 --- .../Reader/ParseNodes/ValueNode.cs | 51 ---- .../Reader/ParsingContext.cs | 41 ++- .../Reader/V2/OpenApiContactDeserializer.cs | 18 +- .../Reader/V2/OpenApiDocumentDeserializer.cs | 89 +++--- .../V2/OpenApiExternalDocsDeserializer.cs | 16 +- .../Reader/V2/OpenApiHeaderDeserializer.cs | 55 ++-- .../Reader/V2/OpenApiInfoDeserializer.cs | 24 +- .../Reader/V2/OpenApiLicenseDeserializer.cs | 16 +- .../Reader/V2/OpenApiOperationDeserializer.cs | 86 +++--- .../Reader/V2/OpenApiParameterDeserializer.cs | 84 +++--- .../Reader/V2/OpenApiPathItemDeserializer.cs | 44 +-- .../Reader/V2/OpenApiPathsDeserializer.cs | 14 +- .../Reader/V2/OpenApiResponseDeserializer.cs | 69 +++-- .../Reader/V2/OpenApiSchemaDeserializer.cs | 86 +++--- .../OpenApiSecurityRequirementDeserializer.cs | 20 +- .../V2/OpenApiSecuritySchemeDeserializer.cs | 37 ++- .../Reader/V2/OpenApiTagDeserializer.cs | 21 +- .../Reader/V2/OpenApiV2Deserializer.cs | 48 ++- .../Reader/V2/OpenApiV2VersionService.cs | 14 +- .../Reader/V2/OpenApiXmlDeserializer.cs | 25 +- .../Reader/V3/OpenApiCallbackDeserializer.cs | 16 +- .../V3/OpenApiComponentsDeserializer.cs | 30 +- .../Reader/V3/OpenApiContactDeserializer.cs | 18 +- .../V3/OpenApiDiscriminatorDeserializer.cs | 19 +- .../Reader/V3/OpenApiDocumentDeserializer.cs | 30 +- .../Reader/V3/OpenApiEncodingDeserializer.cs | 27 +- .../Reader/V3/OpenApiExampleDeserializer.cs | 29 +- .../V3/OpenApiExternalDocsDeserializer.cs | 16 +- .../Reader/V3/OpenApiHeaderDeserializer.cs | 43 ++- .../Reader/V3/OpenApiInfoDeserializer.cs | 24 +- .../Reader/V3/OpenApiLicenseDeserializer.cs | 16 +- .../Reader/V3/OpenApiLinkDeserializer.cs | 26 +- .../Reader/V3/OpenApiMediaTypeDeserializer.cs | 32 +- .../Reader/V3/OpenApiOAuthFlowDeserializer.cs | 25 +- .../V3/OpenApiOAuthFlowsDeserializer.cs | 25 +- .../Reader/V3/OpenApiOperationDeserializer.cs | 49 +-- .../Reader/V3/OpenApiParameterDeserializer.cs | 48 +-- .../Reader/V3/OpenApiPathItemDeserializer.cs | 40 +-- .../Reader/V3/OpenApiPathsDeserializer.cs | 14 +- .../V3/OpenApiRequestBodyDeserializer.cs | 23 +- .../Reader/V3/OpenApiResponseDeserializer.cs | 24 +- .../Reader/V3/OpenApiResponsesDeserializer.cs | 14 +- .../Reader/V3/OpenApiSchemaDeserializer.cs | 93 +++--- .../OpenApiSecurityRequirementDeserializer.cs | 18 +- .../V3/OpenApiSecuritySchemeDeserializer.cs | 39 ++- .../Reader/V3/OpenApiServerDeserializer.cs | 20 +- .../V3/OpenApiServerVariableDeserializer.cs | 18 +- .../Reader/V3/OpenApiTagDeserializer.cs | 23 +- .../Reader/V3/OpenApiV3Deserializer.cs | 61 ++-- .../Reader/V3/OpenApiV3VersionService.cs | 12 +- .../Reader/V3/OpenApiXmlDeserializer.cs | 25 +- .../Reader/V31/OpenApiCallbackDeserializer.cs | 17 +- .../V31/OpenApiComponentsDeserializer.cs | 32 +- .../Reader/V31/OpenApiContactDeserializer.cs | 17 +- .../V31/OpenApiDiscriminatorDeserializer.cs | 26 +- .../Reader/V31/OpenApiDocumentDeserializer.cs | 33 +- .../Reader/V31/OpenApiEncodingDeserializer.cs | 28 +- .../Reader/V31/OpenApiExampleDeserializer.cs | 30 +- .../V31/OpenApiExternalDocsDeserializer.cs | 15 +- .../Reader/V31/OpenApiHeaderDeserializer.cs | 48 ++- .../Reader/V31/OpenApiInfoDeserializer.cs | 29 +- .../Reader/V31/OpenApiLicenseDeserializer.cs | 17 +- .../Reader/V31/OpenApiLinkDeserializer.cs | 29 +- .../V31/OpenApiMediaTypeDeserializer.cs | 41 +-- .../V31/OpenApiOAuthFlowDeserializer.cs | 24 +- .../V31/OpenApiOAuthFlowsDeserializer.cs | 24 +- .../V31/OpenApiOperationDeserializer.cs | 61 ++-- .../V31/OpenApiParameterDeserializer.cs | 55 ++-- .../Reader/V31/OpenApiPathItemDeserializer.cs | 41 +-- .../Reader/V31/OpenApiPathsDeserializer.cs | 13 +- .../V31/OpenApiRequestBodyDeserializer.cs | 26 +- .../Reader/V31/OpenApiResponseDeserializer.cs | 31 +- .../V31/OpenApiResponsesDeserializer.cs | 14 +- .../Reader/V31/OpenApiSchemaDeserializer.cs | 143 +++++---- .../OpenApiSecurityRequirementDeserializer.cs | 18 +- .../V31/OpenApiSecuritySchemeDeserializer.cs | 43 ++- .../Reader/V31/OpenApiServerDeserializer.cs | 22 +- .../V31/OpenApiServerVariableDeserializer.cs | 20 +- .../Reader/V31/OpenApiTagDeserializer.cs | 25 +- .../Reader/V31/OpenApiV31Deserializer.cs | 62 ++-- .../Reader/V31/OpenApiV31VersionService.cs | 12 +- .../Reader/V31/OpenApiXmlDeserializer.cs | 25 +- .../Reader/V32/OpenApiCallbackDeserializer.cs | 15 +- .../V32/OpenApiComponentsDeserializer.cs | 32 +- .../Reader/V32/OpenApiContactDeserializer.cs | 15 +- .../V32/OpenApiDiscriminatorDeserializer.cs | 26 +- .../Reader/V32/OpenApiDocumentDeserializer.cs | 31 +- .../Reader/V32/OpenApiEncodingDeserializer.cs | 38 ++- .../Reader/V32/OpenApiExampleDeserializer.cs | 28 +- .../V32/OpenApiExternalDocsDeserializer.cs | 13 +- .../Reader/V32/OpenApiHeaderDeserializer.cs | 46 ++- .../Reader/V32/OpenApiInfoDeserializer.cs | 27 +- .../Reader/V32/OpenApiLicenseDeserializer.cs | 15 +- .../Reader/V32/OpenApiLinkDeserializer.cs | 27 +- .../V32/OpenApiMediaTypeDeserializer.cs | 43 +-- .../V32/OpenApiOAuthFlowDeserializer.cs | 22 +- .../V32/OpenApiOAuthFlowsDeserializer.cs | 22 +- .../V32/OpenApiOperationDeserializer.cs | 60 ++-- .../V32/OpenApiParameterDeserializer.cs | 53 ++-- .../Reader/V32/OpenApiPathItemDeserializer.cs | 54 ++-- .../Reader/V32/OpenApiPathsDeserializer.cs | 11 +- .../V32/OpenApiRequestBodyDeserializer.cs | 24 +- .../Reader/V32/OpenApiResponseDeserializer.cs | 29 +- .../V32/OpenApiResponsesDeserializer.cs | 12 +- .../Reader/V32/OpenApiSchemaDeserializer.cs | 142 ++++----- .../OpenApiSecurityRequirementDeserializer.cs | 17 +- .../V32/OpenApiSecuritySchemeDeserializer.cs | 45 ++- .../Reader/V32/OpenApiServerDeserializer.cs | 20 +- .../V32/OpenApiServerVariableDeserializer.cs | 18 +- .../Reader/V32/OpenApiTagDeserializer.cs | 30 +- .../Reader/V32/OpenApiV32Deserializer.cs | 61 ++-- .../Reader/V32/OpenApiV32VersionService.cs | 10 +- .../Reader/V32/OpenApiXmlDeserializer.cs | 23 +- .../Services/OpenApiFilterService.cs | 22 +- .../ParseNodeTests.cs | 3 +- .../TestHelper.cs | 8 +- .../V2Tests/OpenApiHeaderTests.cs | 15 +- .../V2Tests/OpenApiOperationTests.cs | 68 ++--- .../V2Tests/OpenApiParameterTests.cs | 63 ++-- .../V2Tests/OpenApiPathItemTests.cs | 19 +- .../V2Tests/OpenApiSchemaTests.cs | 20 +- .../V2Tests/OpenApiSecuritySchemeTests.cs | 26 +- ...enApiCallbackReferenceDeserializerTests.cs | 4 +- ...penApiExampleReferenceDeserializerTests.cs | 4 +- ...OpenApiHeaderReferenceDeserializerTests.cs | 4 +- .../V31Tests/OpenApiInfoTests.cs | 6 +- .../V31Tests/OpenApiLicenseTests.cs | 6 +- .../OpenApiLinkReferenceDeserializerTests.cs | 4 +- .../V31Tests/OpenApiMediaTypeTests.cs | 7 +- ...nApiParameterReferenceDeserializerTests.cs | 4 +- ...enApiPathItemReferenceDeserializerTests.cs | 4 +- ...piRequestBodyReferenceDeserializerTests.cs | 4 +- ...enApiResponseReferenceDeserializerTests.cs | 4 +- ...OpenApiSchemaReferenceDeserializerTests.cs | 4 +- ...ecuritySchemeReferenceDeserializerTests.cs | 8 +- .../V31Tests/OpenApiServerTests.cs | 8 +- .../V31Tests/OpenApiTagDeserializerTests.cs | 10 +- .../OpenApiTagReferenceDeserializerTests.cs | 4 +- ...enApiCallbackReferenceDeserializerTests.cs | 4 +- ...penApiExampleReferenceDeserializerTests.cs | 4 +- ...OpenApiHeaderReferenceDeserializerTests.cs | 4 +- .../V32Tests/OpenApiInfoTests.cs | 4 +- .../V32Tests/OpenApiLicenseTests.cs | 4 +- .../OpenApiLinkReferenceDeserializerTests.cs | 4 +- .../V32Tests/OpenApiMediaTypeTests.cs | 7 +- ...nApiParameterReferenceDeserializerTests.cs | 4 +- ...enApiPathItemReferenceDeserializerTests.cs | 4 +- ...piRequestBodyReferenceDeserializerTests.cs | 4 +- ...enApiResponseReferenceDeserializerTests.cs | 4 +- ...OpenApiSchemaReferenceDeserializerTests.cs | 4 +- ...ecuritySchemeReferenceDeserializerTests.cs | 8 +- .../V32Tests/OpenApiServerTests.cs | 8 +- .../V32Tests/OpenApiTagDeserializerTests.cs | 14 +- .../OpenApiTagReferenceDeserializerTests.cs | 4 +- .../V3Tests/OpenApiMediaTypeTests.cs | 9 +- .../V3Tests/OpenApiParameterTests.cs | 6 +- .../V3Tests/OpenApiSchemaTests.cs | 14 +- .../V3Tests/OpenApiServerTests.cs | 8 +- .../V3Tests/OpenApiTagDeserializerTests.cs | 14 +- .../Reader/MapNodeTests.cs | 22 +- 172 files changed, 2428 insertions(+), 2685 deletions(-) delete mode 100644 src/Microsoft.OpenApi/Reader/ParseNodes/ListNode.cs delete mode 100644 src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs delete mode 100644 src/Microsoft.OpenApi/Reader/ParseNodes/ParseNode.cs delete mode 100644 src/Microsoft.OpenApi/Reader/ParseNodes/PropertyNode.cs delete mode 100644 src/Microsoft.OpenApi/Reader/ParseNodes/RootNode.cs delete mode 100644 src/Microsoft.OpenApi/Reader/ParseNodes/ValueNode.cs diff --git a/src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs b/src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs index 0a45c1b26..96fdf64ef 100644 --- a/src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs +++ b/src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs @@ -1,7 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; +using System.Text.Json.Nodes; using Microsoft.OpenApi.Reader; namespace Microsoft.OpenApi @@ -17,23 +18,25 @@ internal interface IOpenApiVersionService /// Type of element to load /// document fragment node /// A host document instance. + /// The current parsing context. /// Instance of OpenAPIElement - T? LoadElement(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement; + T? LoadElement(JsonNode node, OpenApiDocument doc, ParsingContext context) where T : IOpenApiElement; /// - /// Converts a generic RootNode instance into a strongly typed OpenApiDocument + /// Converts a generic JsonNode instance into a strongly typed OpenApiDocument /// - /// RootNode containing the information to be converted into an OpenAPI Document + /// JsonNode containing the information to be converted into an OpenAPI Document /// Location of where the document that is getting loaded is saved - /// Instance of OpenApiDocument populated with data from rootNode - OpenApiDocument LoadDocument(RootNode rootNode, Uri location); + /// The current parsing context. + /// Instance of OpenApiDocument populated with data from JsonNode + OpenApiDocument LoadDocument(JsonNode JsonNode, Uri location, ParsingContext context); /// /// Gets the description and summary scalar values in a reference object for V3.1 support /// - /// A YamlMappingNode. + /// A Json object. /// The scalar value we're parsing. /// The resulting node value. - string? GetReferenceScalarValues(MapNode mapNode, string scalarValue); + string? GetReferenceScalarValues(JsonObject JsonObject, string scalarValue); } } diff --git a/src/Microsoft.OpenApi/Models/BaseOpenApiReference.cs b/src/Microsoft.OpenApi/Models/BaseOpenApiReference.cs index b45d18787..0939a2e7f 100644 --- a/src/Microsoft.OpenApi/Models/BaseOpenApiReference.cs +++ b/src/Microsoft.OpenApi/Models/BaseOpenApiReference.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; @@ -302,10 +302,9 @@ internal void EnsureHostDocumentIsSet(OpenApiDocument currentDocument) /// The key of the property /// The property value protected internal static string? GetPropertyValueFromNode(JsonObject jsonObject, string key) => - jsonObject.TryGetPropertyValue(key, out var valueNode) && valueNode is JsonValue valueCast && valueCast.TryGetValue(out var strValue) ? strValue : null; - internal virtual void SetMetadataFromMapNode(MapNode mapNode) + jsonObject.TryGetPropertyValue(key, out var JsonNode) && JsonNode is JsonValue valueCast && valueCast.TryGetValue(out var strValue) ? strValue : null; + internal virtual void SetMetadataFromJsonObject(JsonObject jsonObject) { - if (mapNode.JsonNode is not JsonObject jsonObject) return; SetAdditional31MetadataFromMapNode(jsonObject); } diff --git a/src/Microsoft.OpenApi/Models/JsonSchemaReference.cs b/src/Microsoft.OpenApi/Models/JsonSchemaReference.cs index 2893a7d22..fff77e4cc 100644 --- a/src/Microsoft.OpenApi/Models/JsonSchemaReference.cs +++ b/src/Microsoft.OpenApi/Models/JsonSchemaReference.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; diff --git a/src/Microsoft.OpenApi/Reader/BaseOpenApiVersionService.cs b/src/Microsoft.OpenApi/Reader/BaseOpenApiVersionService.cs index 6b98c66e3..59af779ad 100644 --- a/src/Microsoft.OpenApi/Reader/BaseOpenApiVersionService.cs +++ b/src/Microsoft.OpenApi/Reader/BaseOpenApiVersionService.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader; @@ -16,27 +17,27 @@ protected BaseOpenApiVersionService(OpenApiDiagnostic diagnostic) Diagnostic = diagnostic; } - internal abstract Dictionary> Loaders { get; } + internal abstract Dictionary> Loaders { get; } - public abstract OpenApiDocument LoadDocument(RootNode rootNode, Uri location); + public abstract OpenApiDocument LoadDocument(JsonNode JsonNode, Uri location, ParsingContext context); - public T? LoadElement(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement + public T? LoadElement(JsonNode node, OpenApiDocument doc, ParsingContext context) where T : IOpenApiElement { - if (Loaders.TryGetValue(typeof(T), out var loader) && loader(node, doc) is T result) + if (Loaders.TryGetValue(typeof(T), out var loader) && loader(node, doc, context) is T result) { return result; } return default; } - public virtual string? GetReferenceScalarValues(MapNode mapNode, string scalarValue) + public virtual string? GetReferenceScalarValues(JsonObject JsonObject, string scalarValue) { - if (mapNode.Any(static x => !"$ref".Equals(x.Name, StringComparison.OrdinalIgnoreCase)) && - mapNode - .Where(x => x.Name.Equals(scalarValue)) + if (JsonObject.Any(static x => !"$ref".Equals(x.Key, StringComparison.OrdinalIgnoreCase)) && + JsonObject + .Where(x => x.Key.Equals(scalarValue)) .Select(static x => x.Value) - .OfType().FirstOrDefault() is {} valueNode) + .OfType().FirstOrDefault() is {} JsonNode) { - return valueNode.GetScalarValue(); + return JsonNode.GetScalarValue(); } return null; diff --git a/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs b/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs index 023311386..f8d64e579 100644 --- a/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs +++ b/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs @@ -1,20 +1,294 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; +using System.Collections.Generic; using System.Globalization; +using System.Linq; +using System.Text.Json; using System.Text.Json.Nodes; +using System.Text.Json.Serialization; namespace Microsoft.OpenApi.Reader { internal static class JsonNodeHelper { - public static string? GetScalarValue(this JsonNode node) + public static JsonObject CheckMapNode(this JsonNode? node, string nodeName, ParsingContext context) { + if (node is not JsonObject JsonObject) + { + throw new OpenApiReaderException($"{nodeName} must be a map/object", context); + } - var scalarNode = node is JsonValue value ? value : throw new OpenApiException($"Expected scalar value."); + return JsonObject; + } + + public static List CreateList(this JsonNode? node, Func map, OpenApiDocument hostDocument, ParsingContext context) + { + if (node is not JsonArray jsonArray) + { + throw new OpenApiReaderException($"Expected list while parsing {typeof(T).Name}", context); + } + + return jsonArray + .OfType() + .Select(n => map(n, hostDocument, context)) + .Where(static i => i != null) + .ToList(); + } + + public static List CreateListOfAny(this JsonNode? node, ParsingContext context) + { + if (node is not JsonArray jsonArray) + { + throw new OpenApiReaderException("Cannot create a list from this type of node.", context); + } + + return jsonArray.OfType().Select(static n => n.CreateAny()).Where(static i => i != null).ToList(); + } + + public static List CreateSimpleList(this JsonNode? node, Func map, OpenApiDocument? openApiDocument, ParsingContext context) + { + if (node is not JsonArray jsonArray) + { + throw new OpenApiReaderException($"Expected list while parsing {typeof(T).Name}", context); + } + + return jsonArray.OfType().Select(n => + { + if (n is not JsonValue) + { + throw new OpenApiReaderException($"Expected a value while parsing at {context.GetLocation()}."); + } + + return map(n, openApiDocument); + }).ToList(); + } + + public static Dictionary CreateMap(this JsonNode? node, Func map, OpenApiDocument hostDocument, ParsingContext context) + { + if (node is not JsonObject jsonMap) + { + throw new OpenApiReaderException($"Expected map while parsing {typeof(T).Name}", context); + } + + var nodes = jsonMap.Select(n => + { + var key = n.Key; + T value; + try + { + context.StartObject(key); + value = n.Value is JsonObject jsonObject + ? map(jsonObject, hostDocument, context) + : default!; + } + finally + { + context.EndObject(); + } + + return new + { + key, + value + }; + }); + + return nodes.ToDictionary(k => k.key, v => v.value); + } + + public static Dictionary CreateSimpleMap(this JsonNode? node, Func map, ParsingContext context) + { + if (node is not JsonObject jsonMap) + { + throw new OpenApiReaderException($"Expected map while parsing {typeof(T).Name}", context); + } + + var nodes = jsonMap.Select(n => + { + var key = n.Key; + try + { + context.StartObject(key); + var JsonNode = n.Value is JsonValue value + ? value + : throw new OpenApiReaderException($"Expected scalar while parsing {typeof(T).Name}", context); + + return (key, value: map(JsonNode)); + } + finally + { + context.EndObject(); + } + }); + + return nodes.ToDictionary(k => k.key, v => v.value); + } + + public static Dictionary> CreateArrayMap(this JsonNode? node, Func map, OpenApiDocument? openApiDocument, ParsingContext context) + { + if (node is not JsonObject jsonMap) + { + throw new OpenApiReaderException($"Expected map while parsing {typeof(T).Name}", context); + } + + var nodes = jsonMap.Select(n => + { + var key = n.Key; + try + { + context.StartObject(key); + var arrayNode = n.Value is JsonArray value + ? value + : throw new OpenApiReaderException($"Expected array while parsing {typeof(T).Name}", context); + + var values = new HashSet(arrayNode.OfType().Select(item => map(item, openApiDocument))); + + return (key, values); - return Convert.ToString(scalarNode?.GetValue(), CultureInfo.InvariantCulture); + } + finally + { + context.EndObject(); + } + }); + + return nodes.ToDictionary(kvp => kvp.key, kvp => kvp.values); + } + + public static JsonNode CreateAny(this JsonNode? node) + { + return node ?? JsonNullSentinel.JsonNull; + } + + public static string GetRaw(this JsonNode node) + { + return JsonSerializer.Serialize(node, SourceGenerationContext.Default.JsonNode); + } + + public static string? GetScalarValue(this JsonNode? node) + { + var scalarNode = node is JsonValue value ? value : throw new OpenApiException("Expected scalar value."); + + return Convert.ToString(scalarNode.GetValue(), CultureInfo.InvariantCulture); + } + + public static string? GetReferencePointer(this JsonObject jsonObject) + { + return jsonObject.TryGetPropertyValue("$ref", out var refNode) ? refNode?.GetScalarValue() : null; + } + + public static string? GetJsonSchemaIdentifier(this JsonObject jsonObject) + { + return jsonObject.TryGetPropertyValue("$id", out var idNode) ? idNode?.GetScalarValue() : null; + } + + public static string? GetSummaryValue(this JsonObject jsonObject) + { + return jsonObject.TryGetPropertyValue("summary", out var summaryNode) ? summaryNode?.GetScalarValue() : null; + } + + public static string? GetDescriptionValue(this JsonObject jsonObject) + { + return jsonObject.TryGetPropertyValue("description", out var descriptionNode) ? descriptionNode?.GetScalarValue() : null; + } + + public static void ParseMap( + this JsonObject? JsonObject, + T domainObject, + FixedFieldMap fixedFieldMap, + PatternFieldMap patternFieldMap, + OpenApiDocument hostDocument, + ParsingContext context, + Action? unrecognizedProperty = null) + { + if (JsonObject == null) + { + return; + } + + foreach (var propertyNode in JsonObject) + { + ParseField(propertyNode.Key, propertyNode.Value ?? JsonNullSentinel.JsonNull, domainObject, fixedFieldMap, patternFieldMap, hostDocument, context, unrecognizedProperty); + } + } + + private static void ParseField( + string name, + JsonNode value, + T parentInstance, + FixedFieldMap fixedFields, + PatternFieldMap patternFields, + OpenApiDocument hostDocument, + ParsingContext context, + Action? unrecognizedProperty) + { + if (fixedFields.TryGetValue(name, out var fixedFieldMap)) + { + try + { + context.StartObject(name); + fixedFieldMap(parentInstance, value, hostDocument, context); + } + catch (OpenApiReaderException ex) + { + context.Diagnostic.Errors.Add(new(ex)); + } + catch (OpenApiException ex) + { + ex.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new(ex)); + } + finally + { + context.EndObject(); + } + } + else + { + var map = patternFields.Where(p => p.Key(name)).Select(p => p.Value).FirstOrDefault(); + if (map != null) + { + try + { + context.StartObject(name); + map(parentInstance, name, value, hostDocument, context); + } + catch (OpenApiReaderException ex) + { + context.Diagnostic.Errors.Add(new(ex)); + } + catch (OpenApiException ex) + { + ex.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new(ex)); + } + finally + { + context.EndObject(); + } + } + else if (unrecognizedProperty != null) + { + unrecognizedProperty(parentInstance, name, value); + } + else + { + var error = new OpenApiError("", $"{name} is not a valid property at {context.GetLocation()}"); + if ("$schema".Equals(name, StringComparison.OrdinalIgnoreCase)) + { + context.Diagnostic.Warnings.Add(error); + } + else + { + context.Diagnostic.Errors.Add(error); + } + } + } } } + + [JsonSerializable(typeof(JsonNode))] + internal partial class SourceGenerationContext : JsonSerializerContext { } } diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/FixedFieldMap.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/FixedFieldMap.cs index 72188f45a..3d310ba68 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/FixedFieldMap.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/FixedFieldMap.cs @@ -3,10 +3,11 @@ using System; using System.Collections.Generic; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader { - internal class FixedFieldMap : Dictionary> + internal class FixedFieldMap : Dictionary> { } } diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/ListNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/ListNode.cs deleted file mode 100644 index 27cabe6a7..000000000 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/ListNode.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text.Json.Nodes; - -namespace Microsoft.OpenApi.Reader -{ - internal class ListNode : ParseNode, IEnumerable - { - private readonly JsonArray _nodeList; - - public ListNode(ParsingContext context, JsonArray jsonArray) : base( - context, jsonArray) - { - _nodeList = jsonArray; - } - - public override List CreateList(Func map, OpenApiDocument hostDocument) - { - if (_nodeList == null) - { - throw new OpenApiReaderException($"Expected list while parsing {typeof(T).Name}"); - } - - var list = _nodeList - .OfType() - .Select(n => map(new MapNode(Context, n), hostDocument)) - .Where(i => i != null) - .ToList(); - return list; - } - - public override List CreateListOfAny() - { - - var list = _nodeList.OfType().Select(n => Create(Context, n).CreateAny()) - .Where(i => i != null) - .ToList(); - - return list; - } - - public override List CreateSimpleList(Func map, OpenApiDocument openApiDocument) - { - if (_nodeList == null) - { - throw new OpenApiReaderException($"Expected list while parsing {typeof(T).Name}"); - } - - return _nodeList.OfType().Select(n => map(new(Context, n), openApiDocument)).ToList(); - } - - public IEnumerator GetEnumerator() - { - return _nodeList.OfType().Select(n => Create(Context, n)).ToList().GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - /// - /// Create a - /// - /// The created Any object. - public override JsonNode CreateAny() - { - return _nodeList; - } - } -} diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs deleted file mode 100644 index 3b66d549e..000000000 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text.Json; -using System.Text.Json.Nodes; -using System.Text.Json.Serialization; - -namespace Microsoft.OpenApi.Reader -{ - /// - /// Abstraction of a Map to isolate semantic parsing from details of JSON DOM - /// - internal class MapNode : ParseNode, IEnumerable - { - private readonly JsonObject _node; - - private PropertyNode GetPropertyNodeFromJsonNode(string key, JsonNode? node) - { - return new PropertyNode(Context, key, node ?? JsonNullSentinel.JsonNull); - } - - private readonly List _nodes; - public MapNode(ParsingContext context, JsonNode node) : base( - context, node) - { - if (node is not JsonObject mapNode) - { - throw new OpenApiReaderException("Expected map.", Context); - } - - _node = mapNode; - _nodes = _node.Select(p => GetPropertyNodeFromJsonNode(p.Key, p.Value)).ToList(); - } - - public override Dictionary CreateMap(Func map, OpenApiDocument hostDocument) - { - var jsonMap = _node ?? throw new OpenApiReaderException($"Expected map while parsing {typeof(T).Name}", Context); - var nodes = jsonMap.Select( - n => - { - - var key = n.Key; - T value; - try - { - Context.StartObject(key); - value = n.Value is JsonObject jsonObject - ? map(new MapNode(Context, jsonObject), hostDocument) - : default!; - } - finally - { - Context.EndObject(); - } - return new - { - key, - value - }; - }); - - return nodes.ToDictionary(k => k.key, v => v.value); - } - - public override Dictionary CreateSimpleMap(Func map) - { - var jsonMap = _node ?? throw new OpenApiReaderException($"Expected map while parsing {typeof(T).Name}", Context); - var nodes = jsonMap.Select( - n => - { - var key = n.Key; - try - { - Context.StartObject(key); - JsonValue valueNode = n.Value is JsonValue value ? value - : throw new OpenApiReaderException($"Expected scalar while parsing {typeof(T).Name}", Context); - - return (key, value: map(new ValueNode(Context, valueNode))); - } - finally - { - Context.EndObject(); - } - }); - - return nodes.ToDictionary(k => k.key, v => v.value); - } - - public override Dictionary> CreateArrayMap(Func map, OpenApiDocument? openApiDocument) - { - var jsonMap = _node ?? throw new OpenApiReaderException($"Expected map while parsing {typeof(T).Name}", Context); - - var nodes = jsonMap.Select(n => - { - var key = n.Key; - try - { - Context.StartObject(key); - JsonArray arrayNode = n.Value is JsonArray value - ? value - : throw new OpenApiReaderException($"Expected array while parsing {typeof(T).Name}", Context); - - HashSet values = new HashSet(arrayNode.OfType().Select(item => map(new ValueNode(Context, item), openApiDocument))); - - return (key, values); - - } - finally - { - Context.EndObject(); - } - }); - - return nodes.ToDictionary(kvp => kvp.key, kvp => kvp.values); - } - - public IEnumerator GetEnumerator() - { - return _nodes.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string GetRaw() - { - var x = JsonSerializer.Serialize(_node, SourceGenerationContext.Default.JsonObject); - return x; - } - - public string? GetReferencePointer() - { - if (!_node.TryGetPropertyValue("$ref", out JsonNode? refNode)) - { - return null; - } - - return refNode?.GetScalarValue(); - } - - public string? GetJsonSchemaIdentifier() - { - if (!_node.TryGetPropertyValue("$id", out JsonNode? idNode)) - { - return null; - } - - return idNode?.GetScalarValue(); - } - - public string? GetSummaryValue() - { - if (!_node.TryGetPropertyValue("summary", out JsonNode? summaryNode)) - { - return null; - } - - return summaryNode?.GetScalarValue(); - } - - public string? GetDescriptionValue() - { - if (!_node.TryGetPropertyValue("description", out JsonNode? descriptionNode)) - { - return null; - } - - return descriptionNode?.GetScalarValue(); - } - - public string? GetScalarValue(ValueNode key) - { - var keyValue = key.GetScalarValue(); - if (keyValue is not null) - { - var scalarNode = _node[keyValue] is JsonValue jsonValue - ? jsonValue - : throw new OpenApiReaderException($"Expected scalar while parsing {key.GetScalarValue()}", Context); - - return Convert.ToString(scalarNode?.GetValue(), CultureInfo.InvariantCulture); - } - return null; - } - - /// - /// Create an - /// - /// The created Json object. - public override JsonNode CreateAny() - { - return _node; - } - } - - [JsonSerializable(typeof(JsonObject))] - internal partial class SourceGenerationContext : JsonSerializerContext { } -} diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/ParseNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/ParseNode.cs deleted file mode 100644 index bfa248527..000000000 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/ParseNode.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -using System; -using System.Collections.Generic; -using System.Text.Json.Nodes; - -namespace Microsoft.OpenApi.Reader -{ - internal abstract class ParseNode - { - protected ParseNode(ParsingContext parsingContext, JsonNode jsonNode) - { - Context = parsingContext; - JsonNode = jsonNode; - } - - public ParsingContext Context { get; } - - public JsonNode JsonNode { get; } - - public MapNode CheckMapNode(string nodeName) - { - if (this is not MapNode mapNode) - { - throw new OpenApiReaderException($"{nodeName} must be a map/object", Context); - } - - return mapNode; - } - - public static ParseNode Create(ParsingContext context, JsonNode node) - { - if (node is JsonArray listNode) - { - return new ListNode(context, listNode); - } - - if (node is JsonObject mapNode) - { - return new MapNode(context, mapNode); - } - - return new ValueNode(context, node); - } - - public virtual List CreateList(Func map, OpenApiDocument hostDocument) - { - throw new OpenApiReaderException("Cannot create list from this type of node.", Context); - } - - public virtual Dictionary CreateMap(Func map, OpenApiDocument hostDocument) - { - throw new OpenApiReaderException("Cannot create map from this type of node.", Context); - } - - public virtual List CreateSimpleList(Func map, OpenApiDocument openApiDocument) - { - throw new OpenApiReaderException("Cannot create simple list from this type of node.", Context); - } - - public virtual Dictionary CreateSimpleMap(Func map) - { - throw new OpenApiReaderException("Cannot create simple map from this type of node.", Context); - } - - public virtual JsonNode CreateAny() - { - throw new OpenApiReaderException("Cannot create an Any object this type of node.", Context); - } - - public virtual string GetRaw() - { - throw new OpenApiReaderException("Cannot get raw value from this type of node.", Context); - } - - public virtual string GetScalarValue() - { - throw new OpenApiReaderException("Cannot create a scalar value from this type of node.", Context); - } - - public virtual List CreateListOfAny() - { - throw new OpenApiReaderException("Cannot create a list from this type of node.", Context); - } - - public virtual Dictionary> CreateArrayMap(Func map, OpenApiDocument? openApiDocument) - { - throw new OpenApiReaderException("Cannot create array map from this type of node.", Context); - } - } -} diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/PatternFieldMap.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/PatternFieldMap.cs index ee6683939..a099f318d 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/PatternFieldMap.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/PatternFieldMap.cs @@ -3,10 +3,11 @@ using System; using System.Collections.Generic; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader { - internal class PatternFieldMap : Dictionary, Action> + internal class PatternFieldMap : Dictionary, Action> { } } diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/PropertyNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/PropertyNode.cs deleted file mode 100644 index 6ca2cf7ac..000000000 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/PropertyNode.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.Json.Nodes; - -namespace Microsoft.OpenApi.Reader -{ - internal class PropertyNode : ParseNode - { - public PropertyNode(ParsingContext context, string name, JsonNode node) : base( - context, node) - { - Name = name; - Value = Create(context, node); - } - - public string Name { get; set; } - - public ParseNode Value { get; set; } - - public void ParseField( - T parentInstance, - Dictionary> fixedFields, - Dictionary, Action> patternFields, - OpenApiDocument hostDocument) - { - if (fixedFields.TryGetValue(Name, out var fixedFieldMap)) - { - try - { - Context.StartObject(Name); - fixedFieldMap(parentInstance, Value, hostDocument); - } - catch (OpenApiReaderException ex) - { - Context.Diagnostic.Errors.Add(new(ex)); - } - catch (OpenApiException ex) - { - ex.Pointer = Context.GetLocation(); - Context.Diagnostic.Errors.Add(new(ex)); - } - finally - { - Context.EndObject(); - } - } - else - { - var map = patternFields.Where(p => p.Key(Name)).Select(p => p.Value).FirstOrDefault(); - if (map != null) - { - try - { - Context.StartObject(Name); - map(parentInstance, Name, Value, hostDocument); - } - catch (OpenApiReaderException ex) - { - Context.Diagnostic.Errors.Add(new(ex)); - } - catch (OpenApiException ex) - { - ex.Pointer = Context.GetLocation(); - Context.Diagnostic.Errors.Add(new(ex)); - } - finally - { - Context.EndObject(); - } - } - else - { - var error = new OpenApiError("", $"{Name} is not a valid property at {Context.GetLocation()}"); - if ("$schema".Equals(Name, StringComparison.OrdinalIgnoreCase)) - { - Context.Diagnostic.Warnings.Add(error); - } - else - { - Context.Diagnostic.Errors.Add(error); - } - } - } - } - - public override JsonNode CreateAny() - { - throw new NotImplementedException(); - } - } -} diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/RootNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/RootNode.cs deleted file mode 100644 index cac8d5b49..000000000 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/RootNode.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -using System.Text.Json.Nodes; - -namespace Microsoft.OpenApi.Reader -{ - /// - /// Wrapper class around JsonDocument to isolate semantic parsing from details of Json DOM. - /// - internal class RootNode : ParseNode - { - private readonly JsonNode _jsonNode; - - public RootNode( - ParsingContext context, - JsonNode jsonNode) : base(context, jsonNode) - { - _jsonNode = jsonNode; - } - - public ParseNode? Find(JsonPointer referencePointer) - { - if (referencePointer.Find(_jsonNode) is not JsonNode jsonNode) - { - return null; - } - - return Create(Context, jsonNode); - } - - public MapNode GetMap() - { - return new MapNode(Context, _jsonNode); - } - } -} diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/ValueNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/ValueNode.cs deleted file mode 100644 index bf207d741..000000000 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/ValueNode.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -using System; -using System.Globalization; -using System.Text.Json.Nodes; - -namespace Microsoft.OpenApi.Reader -{ - internal class ValueNode : ParseNode - { - private readonly JsonValue _node; - - public ValueNode(ParsingContext context, JsonNode node) : base( - context, node) - { - if (node is not JsonValue scalarNode) - { - throw new OpenApiReaderException($"Expected a value while parsing at {Context.GetLocation()}."); - } - _node = scalarNode; - } - - public override string GetScalarValue() - { - var scalarValue = _node.GetValue(); - return Convert.ToString(scalarValue, CultureInfo.InvariantCulture) - ?? throw new OpenApiReaderException($"Expected a value at {Context.GetLocation()}."); - } - - /// - /// Attempts to get the underlying value directly as the specified type without string conversion. - /// - /// The type to retrieve the value as. - /// The retrieved value if successful. - /// True if the value was successfully converted to the specified type; otherwise, false. - public bool TryGetValue(out T? value) - { - return _node.TryGetValue(out value); - } - - /// - /// Create a - /// - /// The created Any object. - public override JsonNode CreateAny() - { - return _node; - } - } -} diff --git a/src/Microsoft.OpenApi/Reader/ParsingContext.cs b/src/Microsoft.OpenApi/Reader/ParsingContext.cs index b67c4189f..fd95c26ff 100644 --- a/src/Microsoft.OpenApi/Reader/ParsingContext.cs +++ b/src/Microsoft.OpenApi/Reader/ParsingContext.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; @@ -27,7 +27,7 @@ public class ParsingContext public Dictionary>? ExtensionParsers { get; set; } = new(); - internal RootNode? RootNode { get; set; } + internal JsonNode? JsonNode { get; set; } internal List Tags { get; private set; } = new(); /// @@ -62,9 +62,9 @@ public ParsingContext(OpenApiDiagnostic diagnostic) /// An OpenApiDocument populated based on the passed yamlDocument public OpenApiDocument Parse(JsonNode jsonNode, Uri location) { - RootNode = new RootNode(this, jsonNode); + JsonNode = jsonNode; - var inputVersion = GetVersion(RootNode); + var inputVersion = GetVersion(jsonNode); OpenApiDocument doc; @@ -72,26 +72,26 @@ public OpenApiDocument Parse(JsonNode jsonNode, Uri location) { case string version when version.is2_0(): VersionService = new OpenApiV2VersionService(Diagnostic); - doc = VersionService.LoadDocument(RootNode, location); + doc = VersionService.LoadDocument(jsonNode, location, this); this.Diagnostic.SpecificationVersion = OpenApiSpecVersion.OpenApi2_0; ValidateRequiredFields(doc, version); break; case string version when version.is3_0(): VersionService = new OpenApiV3VersionService(Diagnostic); - doc = VersionService.LoadDocument(RootNode, location); + doc = VersionService.LoadDocument(jsonNode, location, this); this.Diagnostic.SpecificationVersion = version.is3_1() ? OpenApiSpecVersion.OpenApi3_1 : OpenApiSpecVersion.OpenApi3_0; ValidateRequiredFields(doc, version); break; case string version when version.is3_1(): VersionService = new OpenApiV31VersionService(Diagnostic); - doc = VersionService.LoadDocument(RootNode, location); + doc = VersionService.LoadDocument(jsonNode, location, this); this.Diagnostic.SpecificationVersion = OpenApiSpecVersion.OpenApi3_1; ValidateRequiredFields(doc, version); break; case string version when version.is3_2(): VersionService = new OpenApiV32VersionService(Diagnostic); - doc = VersionService.LoadDocument(RootNode, location); + doc = VersionService.LoadDocument(jsonNode, location, this); this.Diagnostic.SpecificationVersion = OpenApiSpecVersion.OpenApi3_2; ValidateRequiredFields(doc, version); break; @@ -111,28 +111,26 @@ public OpenApiDocument Parse(JsonNode jsonNode, Uri location) /// An OpenApiDocument populated based on the passed yamlDocument public T? ParseFragment(JsonNode jsonNode, OpenApiSpecVersion version, OpenApiDocument openApiDocument) where T : IOpenApiElement { - var node = ParseNode.Create(this, jsonNode); - var element = default(T); switch (version) { case OpenApiSpecVersion.OpenApi2_0: VersionService = new OpenApiV2VersionService(Diagnostic); - element = this.VersionService.LoadElement(node, openApiDocument); + element = this.VersionService.LoadElement(jsonNode, openApiDocument, this); break; case OpenApiSpecVersion.OpenApi3_0: this.VersionService = new OpenApiV3VersionService(Diagnostic); - element = this.VersionService.LoadElement(node, openApiDocument); + element = this.VersionService.LoadElement(jsonNode, openApiDocument, this); break; case OpenApiSpecVersion.OpenApi3_1: this.VersionService = new OpenApiV31VersionService(Diagnostic); - element = this.VersionService.LoadElement(node, openApiDocument); + element = this.VersionService.LoadElement(jsonNode, openApiDocument, this); break; case OpenApiSpecVersion.OpenApi3_2: this.VersionService = new OpenApiV32VersionService(Diagnostic); - element = this.VersionService.LoadElement(node, openApiDocument); + element = this.VersionService.LoadElement(jsonNode, openApiDocument, this); break; } @@ -142,18 +140,19 @@ public OpenApiDocument Parse(JsonNode jsonNode, Uri location) /// /// Gets the version of the Open API document. /// - private static string GetVersion(RootNode rootNode) + private static string GetVersion(JsonNode JsonNode) { - var versionNode = rootNode.Find(new("/openapi")); + var versionNode = new JsonPointer("/openapi").Find(JsonNode); if (versionNode is not null) { - return versionNode.GetScalarValue().Replace("\"", string.Empty); + return versionNode.GetScalarValue()?.Replace("\"", string.Empty) + ?? throw new OpenApiException("Version node not found."); } - versionNode = rootNode.Find(new("/swagger")); + versionNode = new JsonPointer("/swagger").Find(JsonNode); - return versionNode?.GetScalarValue().Replace("\"", string.Empty) ?? throw new OpenApiException("Version node not found."); + return versionNode?.GetScalarValue()?.Replace("\"", string.Empty) ?? throw new OpenApiException("Version node not found."); } /// @@ -305,10 +304,10 @@ public void StartObject(string objectName) } private void ValidateRequiredFields(OpenApiDocument doc, string version) { - if ((version.is2_0() || version.is3_0()) && (doc.Paths == null) && RootNode is not null) + if ((version.is2_0() || version.is3_0()) && (doc.Paths == null) && JsonNode is not null) { // paths is a required field in OpenAPI 2.0 and 3.0 but optional in 3.1 - RootNode.Context.Diagnostic.Errors.Add(new OpenApiError("", $"Paths is a REQUIRED field at {RootNode.Context.GetLocation()}")); + Diagnostic.Errors.Add(new OpenApiError("", $"Paths is a REQUIRED field at {GetLocation()}")); } } } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiContactDeserializer.cs index dd8c2139f..a09e437b8 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiContactDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V2 @@ -15,11 +17,11 @@ internal static partial class OpenApiV2Deserializer { { "name", - (o, n, t) => o.Name = n.GetScalarValue() + (o, n, t, c) => o.Name = n.GetScalarValue() }, { "url", - (o, n, t) => + (o, n, t, c) => { var url = n.GetScalarValue(); if (url != null) @@ -30,21 +32,21 @@ internal static partial class OpenApiV2Deserializer }, { "email", - (o, n, t) => o.Email = n.GetScalarValue() + (o, n, t, c) => o.Email = n.GetScalarValue() }, }; private static readonly PatternFieldMap _contactPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiContact LoadContact(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiContact LoadContact(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node as MapNode; + var JsonObject = node as JsonObject; var contact = new OpenApiContact(); - ParseMap(mapNode, contact, _contactFixedFields, _contactPatternFields, doc: hostDocument); + ParseMap(JsonObject, contact, _contactFixedFields, _contactPatternFields, hostDocument, context); return contact; } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs index 140ebbe23..c2e86d7e4 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Collections.Generic; using System.Globalization; @@ -17,106 +19,107 @@ internal static partial class OpenApiV2Deserializer private static readonly FixedFieldMap _openApiFixedFields = new() { { - "swagger", (_, _, _) => {} + "swagger", (_, _, _, c) => {} /* Version is valid field but we already parsed it */ }, - {"info", (o, n, _) => o.Info = LoadInfo(n, o)}, - {"host", (_, n, _) => n.Context.SetTempStorage("host", n.GetScalarValue())}, - {"basePath", (_, n, _) => n.Context.SetTempStorage("basePath", n.GetScalarValue())}, + {"info", (o, n, _, c) => o.Info = LoadInfo(n, o, c)}, + {"host", (_, n, _, c) => c.SetTempStorage("host", n.GetScalarValue())}, + {"basePath", (_, n, _, c) => c.SetTempStorage("basePath", n.GetScalarValue())}, { - "schemes", (_, n, doc) => n.Context.SetTempStorage( + "schemes", (_, n, doc, c) => c.SetTempStorage( "schemes", n.CreateSimpleList( - (s, p) => s.GetScalarValue(), doc)) + (s, p) => s.GetScalarValue(), doc, c)) }, { "consumes", - (_, n, doc) => + (_, n, doc, c) => { - var consumes = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc); + var consumes = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc, c); if (consumes.Count > 0) { - n.Context.SetTempStorage(TempStorageKeys.GlobalConsumes, consumes); + c.SetTempStorage(TempStorageKeys.GlobalConsumes, consumes); } } }, { - "produces", (_, n, doc) => { - var produces = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc); + "produces", (_, n, doc, c) => { + var produces = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc, c); if (produces.Count > 0) { - n.Context.SetTempStorage(TempStorageKeys.GlobalProduces, produces); + c.SetTempStorage(TempStorageKeys.GlobalProduces, produces); } } }, - {"paths", (o, n, _) => o.Paths = LoadPaths(n, o)}, + {"paths", (o, n, _, c) => o.Paths = LoadPaths(n, o, c)}, { "definitions", - (o, n, _) => + (o, n, _, c) => { o.Components ??= new(); - o.Components.Schemas = n.CreateMap(LoadSchema, o); + o.Components.Schemas = n.CreateMap(LoadSchema, o, c); } }, { "parameters", - (o, n, doc) => + (o, n, doc, c) => { o.Components ??= new(); - o.Components.Parameters = n.CreateMap(LoadParameter, o) + o.Components.Parameters = n.CreateMap(LoadParameter, o, c) .Where(kvp => kvp.Value != null) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value!); - o.Components.RequestBodies = n.CreateMap((p, d) => + o.Components.RequestBodies = n.CreateMap((p, d, c) => { - var parameter = LoadParameter(node: p, loadRequestBody: true, hostDocument: d); - return parameter != null ? CreateRequestBody(p.Context, parameter) : null; + var parameter = LoadParameter(node: p, loadRequestBody: true, d, c); + return parameter != null ? CreateRequestBody(c, parameter) : null; }, - doc + doc, + c ).Where(kvp => kvp.Value != null) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value!); } }, { - "responses", (o, n, _) => + "responses", (o, n, _, c) => { if (o.Components == null) { o.Components = new(); } - o.Components.Responses = n.CreateMap(LoadResponse, o); + o.Components.Responses = n.CreateMap(LoadResponse, o, c); } }, { - "securityDefinitions", (o, n, _) => + "securityDefinitions", (o, n, _, c) => { if (o.Components == null) { o.Components = new(); } - o.Components.SecuritySchemes = n.CreateMap(LoadSecurityScheme, o); + o.Components.SecuritySchemes = n.CreateMap(LoadSecurityScheme, o, c); } }, - {"security", (o, n, _) => o.Security = n.CreateList(LoadSecurityRequirement, o)}, - {"tags", (o, n, _) => { if (n.CreateList(LoadTag, o) is {Count:> 0} tags) {o.Tags = new HashSet(tags, OpenApiTagComparer.Instance); } } }, - {"externalDocs", (o, n, _) => o.ExternalDocs = LoadExternalDocs(n, o)} + {"security", (o, n, _, c) => o.Security = n.CreateList(LoadSecurityRequirement, o, c)}, + {"tags", (o, n, _, c) => { if (n.CreateList(LoadTag, o, c) is {Count:> 0} tags) {o.Tags = new HashSet(tags, OpenApiTagComparer.Instance); } } }, + {"externalDocs", (o, n, _, c) => o.ExternalDocs = LoadExternalDocs(n, o, c)} }; private static readonly PatternFieldMap _openApiPatternFields = new() { // We have no semantics to verify X- nodes, therefore treat them as just values. - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - private static void MakeServers(IList servers, ParsingContext context, RootNode rootNode) + private static void MakeServers(IList servers, ParsingContext context, JsonNode JsonNode) { var host = context.GetFromTempStorage("host"); var basePath = context.GetFromTempStorage("basePath"); var schemes = context.GetFromTempStorage>("schemes"); - var defaultUrl = rootNode.Context.BaseUrl; + var defaultUrl = context.BaseUrl; // so we don't default to the document path when a host is provided if (string.IsNullOrEmpty(basePath) && !string.IsNullOrEmpty(host)) @@ -133,7 +136,7 @@ private static void MakeServers(IList servers, ParsingContext con //Validate host if (!string.IsNullOrEmpty(host) && !IsHostValid(host!)) { - rootNode.Context.Diagnostic.Errors.Add(new(rootNode.Context.GetLocation(), "Invalid host")); + context.Diagnostic.Errors.Add(new(context.GetLocation(), "Invalid host")); return; } @@ -228,28 +231,28 @@ private static string BuildUrl(string? scheme, string? host, string? basePath) return uriBuilder.ToString(); } - public static OpenApiDocument LoadOpenApi(RootNode rootNode, Uri location) + public static OpenApiDocument LoadOpenApi(JsonNode JsonNode, Uri location, ParsingContext context) { var openApiDoc = new OpenApiDocument { BaseUri = location }; - var openApiNode = rootNode.GetMap(); + var openApiNode = JsonNode.CheckMapNode("OpenAPI", context); - ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, doc: openApiDoc); + ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, openApiDoc, context); if (openApiDoc.Paths != null) { ProcessResponsesMediaTypes( - rootNode.GetMap(), + JsonNode.CheckMapNode("OpenAPI", context), openApiDoc.Paths.Values .SelectMany(path => path.Operations?.Values ?? Enumerable.Empty()) .SelectMany(operation => operation.Responses?.Values ?? Enumerable.Empty()), - openApiNode.Context); + context); } - ProcessResponsesMediaTypes(rootNode.GetMap(), openApiDoc.Components?.Responses?.Values, openApiNode.Context); + ProcessResponsesMediaTypes(JsonNode.CheckMapNode("OpenAPI", context), openApiDoc.Components?.Responses?.Values, context); // Post Process OpenApi Object if (openApiDoc.Servers == null) @@ -257,7 +260,7 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode, Uri location) openApiDoc.Servers = []; } - MakeServers(openApiDoc.Servers, openApiNode.Context, rootNode); + MakeServers(openApiDoc.Servers, context, JsonNode); FixRequestBodyReferences(openApiDoc); @@ -267,19 +270,19 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode, Uri location) return openApiDoc; } - private static void ProcessResponsesMediaTypes(MapNode mapNode, IEnumerable? responses, ParsingContext context) + private static void ProcessResponsesMediaTypes(JsonObject JsonObject, IEnumerable? responses, ParsingContext context) { if (responses != null) { foreach (var response in responses.OfType()) { - ProcessProduces(mapNode, response, context); + ProcessProduces(JsonObject, response, context); if (response.Content != null) { foreach (var mediaType in response.Content.Values.OfType()) { - ProcessAnyFields(mapNode, mediaType, _mediaTypeAnyFields); + ProcessAnyFields(JsonObject, mediaType, _mediaTypeAnyFields, context); } } } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiExternalDocsDeserializer.cs index 6a9102f79..a45e7180f 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiExternalDocsDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V2 @@ -16,7 +18,7 @@ internal static partial class OpenApiV2Deserializer { { OpenApiConstants.Description, - (o, n, _) => + (o, n, _, c) => { var description = n.GetScalarValue(); if (description != null) @@ -27,7 +29,7 @@ internal static partial class OpenApiV2Deserializer }, { OpenApiConstants.Url, - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -41,16 +43,16 @@ internal static partial class OpenApiV2Deserializer private static readonly PatternFieldMap _externalDocsPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiExternalDocs LoadExternalDocs(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiExternalDocs LoadExternalDocs(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("externalDocs"); + var JsonObject = node.CheckMapNode("externalDocs", context); var externalDocs = new OpenApiExternalDocs(); - ParseMap(mapNode, externalDocs, _externalDocsFixedFields, _externalDocsPatternFields, doc: hostDocument); + ParseMap(JsonObject, externalDocs, _externalDocsFixedFields, _externalDocsPatternFields, hostDocument, context); return externalDocs; } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs index a130dbe00..758f0d39a 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Globalization; @@ -16,11 +18,11 @@ internal static partial class OpenApiV2Deserializer { { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "type", - (o, n, _) => + (o, n, _, c) => { var type = n.GetScalarValue(); if (type != null) @@ -31,15 +33,15 @@ internal static partial class OpenApiV2Deserializer }, { "format", - (o, n, _) => GetOrCreateSchema(o).Format = n.GetScalarValue() + (o, n, _, c) => GetOrCreateSchema(o).Format = n.GetScalarValue() }, { "items", - (o, n, doc) => GetOrCreateSchema(o).Items = LoadSchema(n, doc) + (o, n, doc, c) => GetOrCreateSchema(o).Items = LoadSchema(n, doc, c) }, { "collectionFormat", - (o, n, _) => + (o, n, _, c) => { var collectionFormat = n.GetScalarValue(); if (collectionFormat != null) @@ -50,11 +52,11 @@ internal static partial class OpenApiV2Deserializer }, { "default", - (o, n, _) => GetOrCreateSchema(o).Default = n.CreateAny() + (o, n, _, c) => GetOrCreateSchema(o).Default = n.CreateAny() }, { "maximum", - (o, n, _) => + (o, n, _, c) => { var max = n.GetScalarValue(); if (!string.IsNullOrEmpty(max)) @@ -65,11 +67,11 @@ internal static partial class OpenApiV2Deserializer }, { "exclusiveMaximum", - (o, n, _) => GetOrCreateSchema(o).IsExclusiveMaximum = bool.Parse(n.GetScalarValue()) + (o, n, _, c) => GetOrCreateSchema(o).IsExclusiveMaximum = bool.Parse(n.GetScalarValue()!) }, { "minimum", - (o, n, _) => + (o, n, _, c) => { var min = n.GetScalarValue(); if (!string.IsNullOrEmpty(min)) @@ -80,11 +82,11 @@ internal static partial class OpenApiV2Deserializer }, { "exclusiveMinimum", - (o, n, _) => GetOrCreateSchema(o).IsExclusiveMinimum = bool.Parse(n.GetScalarValue()) + (o, n, _, c) => GetOrCreateSchema(o).IsExclusiveMinimum = bool.Parse(n.GetScalarValue()!) }, { "maxLength", - (o, n, _) => + (o, n, _, c) => { var maxLength = n.GetScalarValue(); if (maxLength != null) @@ -95,7 +97,7 @@ internal static partial class OpenApiV2Deserializer }, { "minLength", - (o, n, _) => + (o, n, _, c) => { var minLength = n.GetScalarValue(); if (minLength != null) @@ -106,11 +108,11 @@ internal static partial class OpenApiV2Deserializer }, { "pattern", - (o, n, _) => GetOrCreateSchema(o).Pattern = n.GetScalarValue() + (o, n, _, c) => GetOrCreateSchema(o).Pattern = n.GetScalarValue() }, { "maxItems", - (o, n, _) => + (o, n, _, c) => { var maxItems = n.GetScalarValue(); if (maxItems != null) @@ -121,7 +123,7 @@ internal static partial class OpenApiV2Deserializer }, { "minItems", - (o, n, _) => + (o, n, _, c) => { var minItems = n.GetScalarValue(); if (minItems != null) @@ -132,7 +134,7 @@ internal static partial class OpenApiV2Deserializer }, { "uniqueItems", - (o, n, _) => + (o, n, _, c) => { var uniqueItems = n.GetScalarValue(); if (uniqueItems != null) @@ -143,7 +145,7 @@ internal static partial class OpenApiV2Deserializer }, { "multipleOf", - (o, n, _) => + (o, n, _, c) => { var multipleOf = n.GetScalarValue(); if (multipleOf != null) @@ -154,13 +156,13 @@ internal static partial class OpenApiV2Deserializer }, { "enum", - (o, n, _) => GetOrCreateSchema(o).Enum = n.CreateListOfAny() + (o, n, _, c) => GetOrCreateSchema(o).Enum = n.CreateListOfAny(c) } }; private static readonly PatternFieldMap _headerPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; private static OpenApiSchema GetOrCreateSchema(OpenApiHeader p) @@ -171,21 +173,18 @@ private static OpenApiSchema GetOrCreateSchema(OpenApiHeader p) }; } - public static IOpenApiHeader LoadHeader(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiHeader LoadHeader(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("header"); + var JsonObject = node.CheckMapNode("header", context); var header = new OpenApiHeader(); - foreach (var property in mapNode) - { - property.ParseField(header, _headerFixedFields, _headerPatternFields, hostDocument); - } + ParseMap(JsonObject, header, _headerFixedFields, _headerPatternFields, hostDocument, context); - var schema = node.Context.GetFromTempStorage("schema"); + var schema = context.GetFromTempStorage("schema"); if (schema != null) { header.Schema = schema; - node.Context.SetTempStorage("schema", null); + context.SetTempStorage("schema", null); } return header; diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiInfoDeserializer.cs index fc016928c..14cab9cb2 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiInfoDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V2 @@ -15,15 +17,15 @@ internal static partial class OpenApiV2Deserializer { { "title", - (o, n, _) => o.Title = n.GetScalarValue() + (o, n, _, c) => o.Title = n.GetScalarValue() }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "termsOfService", - (o, n, _) => + (o, n, _, c) => { var terms = n.GetScalarValue(); if (terms != null) @@ -34,30 +36,30 @@ internal static partial class OpenApiV2Deserializer }, { "contact", - (o, n, t) => o.Contact = LoadContact(n, t) + (o, n, t, c) => o.Contact = LoadContact(n, t, c) }, { "license", - (o, n, t) => o.License = LoadLicense(n, t) + (o, n, t, c) => o.License = LoadLicense(n, t, c) }, { "version", - (o, n, _) => o.Version = n.GetScalarValue() + (o, n, _, c) => o.Version = n.GetScalarValue() } }; private static readonly PatternFieldMap _infoPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiInfo LoadInfo(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiInfo LoadInfo(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Info"); + var JsonObject = node.CheckMapNode("Info", context); var info = new OpenApiInfo(); - ParseMap(mapNode, info, _infoFixedFields, _infoPatternFields, doc: hostDocument); + ParseMap(JsonObject, info, _infoFixedFields, _infoPatternFields, hostDocument, context); return info; } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiLicenseDeserializer.cs index 40539085d..74f6a0cee 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiLicenseDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V2 @@ -15,11 +17,11 @@ internal static partial class OpenApiV2Deserializer { { "name", - (o, n, _) => o.Name = n.GetScalarValue() + (o, n, _, c) => o.Name = n.GetScalarValue() }, { "url", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -32,16 +34,16 @@ internal static partial class OpenApiV2Deserializer private static readonly PatternFieldMap _licensePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiLicense LoadLicense(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiLicense LoadLicense(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("OpenApiLicense"); + var JsonObject = node.CheckMapNode("OpenApiLicense", context); var license = new OpenApiLicense(); - ParseMap(mapNode, license, _licenseFixedFields, _licensePatternFields, doc: hostDocument); + ParseMap(JsonObject, license, _licenseFixedFields, _licensePatternFields, hostDocument, context); return license; } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiOperationDeserializer.cs index b30073426..392741a7c 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiOperationDeserializer.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.Collections.Generic; @@ -18,16 +18,17 @@ internal static partial class OpenApiV2Deserializer new() { { - "tags", (o, n, doc) => { + "tags", (o, n, doc, c) => { if (n.CreateSimpleList( - (valueNode, doc) => + (jsonNode, document) => { - var val = valueNode.GetScalarValue(); + var val = jsonNode.GetScalarValue(); if (string.IsNullOrEmpty(val)) return null; // Avoid exception on empty tag, we'll remove these from the list further on - return LoadTagByReference(val , doc); - }, - doc) + return LoadTagByReference(val!, document); + }, + doc, + c) // Filter out empty tags instead of excepting on them .OfType().ToList() is {Count: > 0} tags) { @@ -37,49 +38,49 @@ internal static partial class OpenApiV2Deserializer }, { "summary", - (o, n, _) => o.Summary = n.GetScalarValue() + (o, n, _, c) => o.Summary = n.GetScalarValue() }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "externalDocs", - (o, n, t) => o.ExternalDocs = LoadExternalDocs(n, t) + (o, n, t, c) => o.ExternalDocs = LoadExternalDocs(n, t, c) }, { "operationId", - (o, n, _) => o.OperationId = n.GetScalarValue() + (o, n, _, c) => o.OperationId = n.GetScalarValue() }, { "parameters", - (o, n, t) => o.Parameters = n.CreateList(LoadParameter, t) + (o, n, t, c) => o.Parameters = n.CreateList(LoadParameter, t, c) .OfType() .ToList() }, { - "consumes", (_, n, doc) => { - var consumes = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc); + "consumes", (_, n, doc, c) => { + var consumes = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc, c); if (consumes.Count > 0) { - n.Context.SetTempStorage(TempStorageKeys.OperationConsumes,consumes); + c.SetTempStorage(TempStorageKeys.OperationConsumes,consumes); } } }, { - "produces", (_, n, doc) => { - var produces = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc); + "produces", (_, n, doc, c) => { + var produces = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc, c); if (produces.Count > 0) { - n.Context.SetTempStorage(TempStorageKeys.OperationProduces, produces); + c.SetTempStorage(TempStorageKeys.OperationProduces, produces); } } }, { "responses", - (o, n, t) => o.Responses = LoadResponses(n, t) + (o, n, t, c) => o.Responses = LoadResponses(n, t, c) }, { "deprecated", - (o, n, _) => + (o, n, _, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -90,9 +91,9 @@ internal static partial class OpenApiV2Deserializer }, { "security", - (o, n, t) => { if (n.JsonNode is JsonArray) + (o, n, t, c) => { if (n is JsonArray) { - o.Security = n.CreateList(LoadSecurityRequirement, t); + o.Security = n.CreateList(LoadSecurityRequirement, t, c); } } }, }; @@ -100,7 +101,7 @@ internal static partial class OpenApiV2Deserializer private static readonly PatternFieldMap _operationPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; private static readonly FixedFieldMap _responsesFixedFields = new(); @@ -108,61 +109,62 @@ internal static partial class OpenApiV2Deserializer private static readonly PatternFieldMap _responsesPatternFields = new() { - {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t) => o.Add(p, LoadResponse(n, t))}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t, c) => o.Add(p, LoadResponse(n, t, c))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - internal static OpenApiOperation LoadOperation(ParseNode node, OpenApiDocument hostDocument) + internal static OpenApiOperation LoadOperation(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { // Reset these temp storage parameters for each operation. - node.Context.SetTempStorage(TempStorageKeys.BodyParameter, null); - node.Context.SetTempStorage(TempStorageKeys.FormParameters, null); - node.Context.SetTempStorage(TempStorageKeys.OperationProduces, null); - node.Context.SetTempStorage(TempStorageKeys.OperationConsumes, null); + context.SetTempStorage(TempStorageKeys.BodyParameter, null); + context.SetTempStorage(TempStorageKeys.FormParameters, null); + context.SetTempStorage(TempStorageKeys.OperationProduces, null); + context.SetTempStorage(TempStorageKeys.OperationConsumes, null); - var mapNode = node.CheckMapNode("Operation"); + var JsonObject = node.CheckMapNode("Operation", context); var operation = new OpenApiOperation(); - ParseMap(mapNode, operation, _operationFixedFields, _operationPatternFields, doc: hostDocument); + ParseMap(JsonObject, operation, _operationFixedFields, _operationPatternFields, hostDocument, context); // Build request body based on information determined while parsing OpenApiOperation - var bodyParameter = node.Context.GetFromTempStorage(TempStorageKeys.BodyParameter); + var bodyParameter = context.GetFromTempStorage(TempStorageKeys.BodyParameter); if (bodyParameter != null) { - operation.RequestBody = CreateRequestBody(node.Context, bodyParameter); + operation.RequestBody = CreateRequestBody(context, bodyParameter); } else { - var formParameters = node.Context.GetFromTempStorage>(TempStorageKeys.FormParameters); + var formParameters = context.GetFromTempStorage>(TempStorageKeys.FormParameters); if (formParameters != null) { - operation.RequestBody = CreateFormBody(node.Context, formParameters); + operation.RequestBody = CreateFormBody(context, formParameters); } } + var operationProduces = context.GetFromTempStorage>(TempStorageKeys.OperationProduces); var responses = operation.Responses; - if (responses is not null) + if ((operationProduces is not null || JsonObject.ContainsKey("produces")) && responses is not null) { foreach (var response in responses.Values.OfType()) { - ProcessProduces(node.CheckMapNode("responses"), response, node.Context); + ProcessProduces(JsonObject, response, context); } } // Reset so that it's not picked up later - node.Context.SetTempStorage(TempStorageKeys.OperationProduces, null); + context.SetTempStorage(TempStorageKeys.OperationProduces, null); return operation; } - public static OpenApiResponses LoadResponses(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiResponses LoadResponses(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Responses"); + var JsonObject = node.CheckMapNode("Responses", context); var domainObject = new OpenApiResponses(); - ParseMap(mapNode, domainObject, _responsesFixedFields, _responsesPatternFields, doc: hostDocument); + ParseMap(JsonObject, domainObject, _responsesFixedFields, _responsesPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs index 9d31d409d..ab77e17c4 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Collections.Generic; using System.Globalization; @@ -18,7 +20,7 @@ internal static partial class OpenApiV2Deserializer { { "name", - (o, n, t) => o.Name = n.GetScalarValue() + (o, n, t, c) => o.Name = n.GetScalarValue() }, { "in", @@ -26,11 +28,11 @@ internal static partial class OpenApiV2Deserializer }, { "description", - (o, n, t) => o.Description = n.GetScalarValue() + (o, n, t, c) => o.Description = n.GetScalarValue() }, { "required", - (o, n, t) => + (o, n, t, c) => { var required = n.GetScalarValue(); if (required != null) @@ -41,7 +43,7 @@ internal static partial class OpenApiV2Deserializer }, { "deprecated", - (o, n, t) => + (o, n, t, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -52,7 +54,7 @@ internal static partial class OpenApiV2Deserializer }, { "allowEmptyValue", - (o, n, t) => + (o, n, t, c) => { var allowEmptyValue = n.GetScalarValue(); if (allowEmptyValue != null) @@ -63,7 +65,7 @@ internal static partial class OpenApiV2Deserializer }, { "type", - (o, n, t) => + (o, n, t, c) => { var type = n.GetScalarValue(); if (type != null) @@ -79,11 +81,11 @@ internal static partial class OpenApiV2Deserializer }, { "items", - (o, n, t) => GetOrCreateSchema(o).Items = LoadSchema(n, t) + (o, n, t, c) => GetOrCreateSchema(o).Items = LoadSchema(n, t, c) }, { "collectionFormat", - (o, n, t) => + (o, n, t, c) => { var collectionFormat = n.GetScalarValue(); if (collectionFormat != null) @@ -94,11 +96,11 @@ internal static partial class OpenApiV2Deserializer }, { "format", - (o, n, t) => GetOrCreateSchema(o).Format = n.GetScalarValue() + (o, n, t, c) => GetOrCreateSchema(o).Format = n.GetScalarValue() }, { "minimum", - (o, n, t) => + (o, n, t, c) => { var min = n.GetScalarValue(); if (!string.IsNullOrEmpty(min)) @@ -109,7 +111,7 @@ internal static partial class OpenApiV2Deserializer }, { "maximum", - (o, n, t) => + (o, n, t, c) => { var max = n.GetScalarValue(); if (!string.IsNullOrEmpty(max)) @@ -120,7 +122,7 @@ internal static partial class OpenApiV2Deserializer }, { "maxLength", - (o, n, t) => + (o, n, t, c) => { var maxLength = n.GetScalarValue(); if (maxLength != null) @@ -131,7 +133,7 @@ internal static partial class OpenApiV2Deserializer }, { "minLength", - (o, n, t) => + (o, n, t, c) => { var minLength = n.GetScalarValue(); if (minLength != null) @@ -142,7 +144,7 @@ internal static partial class OpenApiV2Deserializer }, { "readOnly", - (o, n, t) => + (o, n, t, c) => { var readOnly = n.GetScalarValue(); if (readOnly != null) @@ -153,19 +155,19 @@ internal static partial class OpenApiV2Deserializer }, { "default", - (o, n, t) => GetOrCreateSchema(o).Default = n.CreateAny() + (o, n, t, c) => GetOrCreateSchema(o).Default = n.CreateAny() }, { "pattern", - (o, n, t) => GetOrCreateSchema(o).Pattern = n.GetScalarValue() + (o, n, t, c) => GetOrCreateSchema(o).Pattern = n.GetScalarValue() }, { "enum", - (o, n, t) => GetOrCreateSchema(o).Enum = n.CreateListOfAny() + (o, n, t, c) => GetOrCreateSchema(o).Enum = n.CreateListOfAny(c) }, { "schema", - (o, n, t) => o.Schema = LoadSchema(n, t) + (o, n, t, c) => o.Schema = LoadSchema(n, t, c) }, { "x-examples", @@ -177,7 +179,7 @@ internal static partial class OpenApiV2Deserializer new() { {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase) && !s.Equals(OpenApiConstants.ExamplesExtension, StringComparison.OrdinalIgnoreCase), - (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; private static void LoadStyle(OpenApiParameter p, string v) @@ -209,10 +211,10 @@ private static void LoadStyle(OpenApiParameter p, string v) } } - private static void LoadParameterExamplesExtension(OpenApiParameter parameter, ParseNode node, OpenApiDocument? hostDocument) + private static void LoadParameterExamplesExtension(OpenApiParameter parameter, JsonNode node, OpenApiDocument? hostDocument, ParsingContext context) { - var examples = LoadExamplesExtension(node); - node.Context.SetTempStorage(TempStorageKeys.Examples, examples, parameter); + var examples = LoadExamplesExtension(node, context); + context.SetTempStorage(TempStorageKeys.Examples, examples, parameter); } private static OpenApiSchema GetOrCreateSchema(OpenApiParameter p) @@ -223,22 +225,22 @@ private static OpenApiSchema GetOrCreateSchema(OpenApiParameter p) }; } - private static void ProcessIn(OpenApiParameter o, ParseNode n, OpenApiDocument hostDocument) + private static void ProcessIn(OpenApiParameter o, JsonNode n, OpenApiDocument hostDocument, ParsingContext context) { var value = n.GetScalarValue(); switch (value) { case "body": - n.Context.SetTempStorage(TempStorageKeys.ParameterIsBodyOrFormData, true); - n.Context.SetTempStorage(TempStorageKeys.BodyParameter, o); + context.SetTempStorage(TempStorageKeys.ParameterIsBodyOrFormData, true); + context.SetTempStorage(TempStorageKeys.BodyParameter, o); break; case "formData": - n.Context.SetTempStorage(TempStorageKeys.ParameterIsBodyOrFormData, true); - var formParameters = n.Context.GetFromTempStorage>("formParameters"); + context.SetTempStorage(TempStorageKeys.ParameterIsBodyOrFormData, true); + var formParameters = context.GetFromTempStorage>("formParameters"); if (formParameters == null) { formParameters = new(); - n.Context.SetTempStorage("formParameters", formParameters); + context.SetTempStorage("formParameters", formParameters); } formParameters.Add(o); @@ -257,19 +259,19 @@ private static void ProcessIn(OpenApiParameter o, ParseNode n, OpenApiDocument h } } - public static IOpenApiParameter? LoadParameter(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiParameter? LoadParameter(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - return LoadParameter(node, false, hostDocument); + return LoadParameter(node, false, hostDocument, context); } - public static IOpenApiParameter? LoadParameter(ParseNode node, bool loadRequestBody, OpenApiDocument hostDocument) + public static IOpenApiParameter? LoadParameter(JsonNode node, bool loadRequestBody, OpenApiDocument hostDocument, ParsingContext context) { // Reset the local variables every time this method is called. - node.Context.SetTempStorage(TempStorageKeys.ParameterIsBodyOrFormData, false); + context.SetTempStorage(TempStorageKeys.ParameterIsBodyOrFormData, false); - var mapNode = node.CheckMapNode("parameter"); + var JsonObject = node.CheckMapNode("parameter", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { @@ -279,25 +281,25 @@ private static void ProcessIn(OpenApiParameter o, ParseNode n, OpenApiDocument h var parameter = new OpenApiParameter(); - ParseMap(mapNode, parameter, _parameterFixedFields, _parameterPatternFields, doc: hostDocument); + ParseMap(JsonObject, parameter, _parameterFixedFields, _parameterPatternFields, hostDocument, context); - var schema = node.Context.GetFromTempStorage("schema"); + var schema = context.GetFromTempStorage("schema"); if (schema != null) { parameter.Schema = schema; - node.Context.SetTempStorage("schema", null); + context.SetTempStorage("schema", null); } // load examples from storage and add them to the parameter - var examples = node.Context.GetFromTempStorage>(TempStorageKeys.Examples, parameter); + var examples = context.GetFromTempStorage>(TempStorageKeys.Examples, parameter); if (examples != null) { parameter.Examples = examples; - node.Context.SetTempStorage("examples", null); + context.SetTempStorage("examples", null); } var isBodyOrFormData = false; - var paramData = node.Context.GetFromTempStorage(TempStorageKeys.ParameterIsBodyOrFormData); + var paramData = context.GetFromTempStorage(TempStorageKeys.ParameterIsBodyOrFormData); if (paramData is bool boolValue) { isBodyOrFormData = boolValue; diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiPathItemDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiPathItemDeserializer.cs index a090dce49..867685445 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiPathItemDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiPathItemDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Collections.Generic; using System.Linq; @@ -16,16 +18,16 @@ internal static partial class OpenApiV2Deserializer { private static readonly FixedFieldMap _pathItemFixedFields = new() { - {"get", (o, n, t) => o.AddOperation(HttpMethod.Get, LoadOperation(n, t))}, - {"put", (o, n, t) => o.AddOperation(HttpMethod.Put, LoadOperation(n, t))}, - {"post", (o, n, t) => o.AddOperation(HttpMethod.Post, LoadOperation(n, t))}, - {"delete", (o, n, t) => o.AddOperation(HttpMethod.Delete, LoadOperation(n, t))}, - {"options", (o, n, t) => o.AddOperation(HttpMethod.Options, LoadOperation(n, t))}, - {"head", (o, n, t) => o.AddOperation(HttpMethod.Head, LoadOperation(n, t))}, + {"get", (o, n, t, c) => o.AddOperation(HttpMethod.Get, LoadOperation(n, t, c))}, + {"put", (o, n, t, c) => o.AddOperation(HttpMethod.Put, LoadOperation(n, t, c))}, + {"post", (o, n, t, c) => o.AddOperation(HttpMethod.Post, LoadOperation(n, t, c))}, + {"delete", (o, n, t, c) => o.AddOperation(HttpMethod.Delete, LoadOperation(n, t, c))}, + {"options", (o, n, t, c) => o.AddOperation(HttpMethod.Options, LoadOperation(n, t, c))}, + {"head", (o, n, t, c) => o.AddOperation(HttpMethod.Head, LoadOperation(n, t, c))}, #if NETSTANDARD2_1_OR_GREATER - {"patch", (o, n, t) => o.AddOperation(HttpMethod.Patch, LoadOperation(n, t))}, + {"patch", (o, n, t, c) => o.AddOperation(HttpMethod.Patch, LoadOperation(n, t, c))}, #else - {"patch", (o, n, t) => o.AddOperation(new HttpMethod("PATCH"), LoadOperation(n, t))}, + {"patch", (o, n, t, c) => o.AddOperation(new HttpMethod("PATCH"), LoadOperation(n, t, c))}, #endif { "parameters", @@ -36,34 +38,34 @@ internal static partial class OpenApiV2Deserializer private static readonly PatternFieldMap _pathItemPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))}, }; - public static OpenApiPathItem LoadPathItem(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiPathItem LoadPathItem(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("PathItem"); + var JsonObject = node.CheckMapNode("PathItem", context); var pathItem = new OpenApiPathItem(); - ParseMap(mapNode, pathItem, _pathItemFixedFields, _pathItemPatternFields, doc: hostDocument); + ParseMap(JsonObject, pathItem, _pathItemFixedFields, _pathItemPatternFields, hostDocument, context); return pathItem; } - private static void LoadPathParameters(OpenApiPathItem pathItem, ParseNode node, OpenApiDocument hostDocument) + private static void LoadPathParameters(OpenApiPathItem pathItem, JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - node.Context.SetTempStorage(TempStorageKeys.BodyParameter, null); - node.Context.SetTempStorage(TempStorageKeys.FormParameters, null); + context.SetTempStorage(TempStorageKeys.BodyParameter, null); + context.SetTempStorage(TempStorageKeys.FormParameters, null); - pathItem.Parameters = node.CreateList(LoadParameter, hostDocument) + pathItem.Parameters = node.CreateList(LoadParameter, hostDocument, context) .OfType() .ToList(); // Build request body based on information determined while parsing OpenApiOperation - var bodyParameter = node.Context.GetFromTempStorage(TempStorageKeys.BodyParameter); + var bodyParameter = context.GetFromTempStorage(TempStorageKeys.BodyParameter); if (bodyParameter is not null && pathItem.Operations is not null) { - var requestBody = CreateRequestBody(node.Context, bodyParameter); + var requestBody = CreateRequestBody(context, bodyParameter); foreach (var opPair in pathItem.Operations.Where(x => x.Value.RequestBody is null)) { if (opPair.Key == HttpMethod.Post || opPair.Key == HttpMethod.Put @@ -80,10 +82,10 @@ private static void LoadPathParameters(OpenApiPathItem pathItem, ParseNode node, } else { - var formParameters = node.Context.GetFromTempStorage>(TempStorageKeys.FormParameters); + var formParameters = context.GetFromTempStorage>(TempStorageKeys.FormParameters); if (formParameters is not null && pathItem.Operations is not null) { - var requestBody = CreateFormBody(node.Context, formParameters); + var requestBody = CreateFormBody(context, formParameters); foreach (var opPair in pathItem.Operations.Where(x => x.Value.RequestBody is null)) { if (opPair.Key == HttpMethod.Post || opPair.Key == HttpMethod.Put diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiPathsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiPathsDeserializer.cs index 4f0e25b00..23a5aad7d 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiPathsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiPathsDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V2 @@ -15,17 +17,17 @@ internal static partial class OpenApiV2Deserializer private static readonly PatternFieldMap _pathsPatternFields = new() { - {s => s.StartsWith("/", StringComparison.OrdinalIgnoreCase), (o, k, n, t) => o.Add(k, LoadPathItem(n, t))}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith("/", StringComparison.OrdinalIgnoreCase), (o, k, n, t, c) => o.Add(k, LoadPathItem(n, t, c))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiPaths LoadPaths(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiPaths LoadPaths(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Paths"); + var JsonObject = node.CheckMapNode("Paths", context); var domainObject = new OpenApiPaths(); - ParseMap(mapNode, domainObject, _pathsFixedFields, _pathsPatternFields, doc: hostDocument); + ParseMap(JsonObject, domainObject, _pathsFixedFields, _pathsPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs index 7a474d3fc..7aafd1e48 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Collections.Generic; using System.Linq; @@ -17,11 +19,11 @@ internal static partial class OpenApiV2Deserializer { { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "headers", - (o, n, t) => o.Headers = n.CreateMap(LoadHeader, t) + (o, n, t, c) => o.Headers = n.CreateMap(LoadHeader, t, c) }, { "examples", LoadExamples @@ -31,7 +33,7 @@ internal static partial class OpenApiV2Deserializer }, { "schema", - (o, n, t) => n.Context.SetTempStorage(TempStorageKeys.ResponseSchema, LoadSchema(n, t), o) + (o, n, t, c) => c.SetTempStorage(TempStorageKeys.ResponseSchema, LoadSchema(n, t, c), o) }, }; @@ -39,7 +41,7 @@ internal static partial class OpenApiV2Deserializer new() { {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase) && !s.Equals(OpenApiConstants.ExamplesExtension, StringComparison.OrdinalIgnoreCase), - (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; private static readonly AnyFieldMap _mediaTypeAnyFields = @@ -54,7 +56,7 @@ internal static partial class OpenApiV2Deserializer } }; - private static void ProcessProduces(MapNode mapNode, OpenApiResponse response, ParsingContext context) + private static void ProcessProduces(JsonObject JsonObject, OpenApiResponse response, ParsingContext context) { if (response.Content == null) { @@ -80,7 +82,7 @@ private static void ProcessProduces(MapNode mapNode, OpenApiResponse response, P if (schema != null) { openApiMediaType.Schema = schema; - ProcessAnyFields(mapNode, openApiMediaType, _mediaTypeAnyFields); + ProcessAnyFields(JsonObject, openApiMediaType, _mediaTypeAnyFields, context); } } else @@ -100,58 +102,58 @@ private static void ProcessProduces(MapNode mapNode, OpenApiResponse response, P context.SetTempStorage(TempStorageKeys.ResponseProducesSet, true, response); } - private static void LoadResponseExamplesExtension(OpenApiResponse response, ParseNode node, OpenApiDocument? hostDocument) + private static void LoadResponseExamplesExtension(OpenApiResponse response, JsonNode node, OpenApiDocument? hostDocument, ParsingContext context) { - var examples = LoadExamplesExtension(node); - node.Context.SetTempStorage(TempStorageKeys.Examples, examples, response); + var examples = LoadExamplesExtension(node, context); + context.SetTempStorage(TempStorageKeys.Examples, examples, response); } - private static Dictionary LoadExamplesExtension(ParseNode node) + private static Dictionary LoadExamplesExtension(JsonNode node, ParsingContext context) { - var mapNode = node.CheckMapNode(OpenApiConstants.ExamplesExtension); + var JsonObject = node.CheckMapNode(OpenApiConstants.ExamplesExtension, context); var examples = new Dictionary(); - foreach (var examplesNode in mapNode) + foreach (var examplesNode in JsonObject) { // Load the media type node as an OpenApiExample object var example = new OpenApiExample(); - var exampleNode = examplesNode.Value.CheckMapNode(examplesNode.Name); - foreach (var valueNode in exampleNode) + var exampleNode = examplesNode.Value.CheckMapNode(examplesNode.Key, context); + foreach (var JsonNode in exampleNode) { - switch (valueNode.Name.ToLowerInvariant()) + switch (JsonNode.Key.ToLowerInvariant()) { case "summary": - example.Summary = valueNode.Value.GetScalarValue(); + example.Summary = JsonNode.Value.GetScalarValue(); break; case "description": - example.Description = valueNode.Value.GetScalarValue(); + example.Description = JsonNode.Value.GetScalarValue(); break; case "value": - example.Value = valueNode.Value.CreateAny(); + example.Value = JsonNode.Value.CreateAny(); break; case "externalValue": - example.ExternalValue = valueNode.Value.GetScalarValue(); + example.ExternalValue = JsonNode.Value.GetScalarValue(); break; } } - examples.Add(examplesNode.Name, example); + examples.Add(examplesNode.Key, example); } return examples; } - private static void LoadExamples(OpenApiResponse response, ParseNode node, OpenApiDocument? hostDocument) + private static void LoadExamples(OpenApiResponse response, JsonNode node, OpenApiDocument? hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("examples"); + var JsonObject = node.CheckMapNode("examples", context); - foreach (var mediaTypeNode in mapNode) + foreach (var mediaTypeNode in JsonObject) { - LoadExample(response, mediaTypeNode.Name, mediaTypeNode.Value); + LoadExample(response, mediaTypeNode.Key, mediaTypeNode.Value, context); } } - private static void LoadExample(OpenApiResponse response, string mediaType, ParseNode node) + private static void LoadExample(OpenApiResponse response, string mediaType, JsonNode? node, ParsingContext context) { var exampleNode = node.CreateAny(); @@ -166,7 +168,7 @@ private static void LoadExample(OpenApiResponse response, string mediaType, Pars { mediaTypeObject = new() { - Schema = node.Context.GetFromTempStorage(TempStorageKeys.ResponseSchema, response) + Schema = context.GetFromTempStorage(TempStorageKeys.ResponseSchema, response) }; response.Content.Add(mediaType, mediaTypeObject); } @@ -174,11 +176,11 @@ private static void LoadExample(OpenApiResponse response, string mediaType, Pars mediaTypeObject.Example = exampleNode; } - public static IOpenApiResponse LoadResponse(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiResponse LoadResponse(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("response"); + var JsonObject = node.CheckMapNode("response", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); @@ -187,17 +189,14 @@ public static IOpenApiResponse LoadResponse(ParseNode node, OpenApiDocument host var response = new OpenApiResponse(); - foreach (var property in mapNode) - { - property.ParseField(response, _responseFixedFields, _responsePatternFields, hostDocument); - } + ParseMap(JsonObject, response, _responseFixedFields, _responsePatternFields, hostDocument, context); if (response.Content?.Values is not null) { foreach (var mediaType in response.Content.Values.OfType()) { if (mediaType.Schema != null) { - ProcessAnyFields(mapNode, mediaType, _mediaTypeAnyFields); + ProcessAnyFields(JsonObject, mediaType, _mediaTypeAnyFields, context); } } } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs index 8c4104cc3..a22853a01 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System.Collections.Generic; using System.Globalization; using System; @@ -18,11 +20,11 @@ internal static partial class OpenApiV2Deserializer { { "title", - (o, n, _) => o.Title = n.GetScalarValue() + (o, n, _, c) => o.Title = n.GetScalarValue() }, { "multipleOf", - (o, n, _) => + (o, n, _, c) => { var multipleOf = n.GetScalarValue(); if (multipleOf != null) @@ -33,7 +35,7 @@ internal static partial class OpenApiV2Deserializer }, { "maximum", - (o, n,_) => + (o, n, _, c) => { var max = n.GetScalarValue(); if (!string.IsNullOrEmpty(max)) @@ -44,11 +46,11 @@ internal static partial class OpenApiV2Deserializer }, { "exclusiveMaximum", - (o, n, _) => o.IsExclusiveMaximum = bool.Parse(n.GetScalarValue()) + (o, n, _, c) => o.IsExclusiveMaximum = bool.Parse(n.GetScalarValue()!) }, { "minimum", - (o, n, _) => + (o, n, _, c) => { var min = n.GetScalarValue(); if (!string.IsNullOrEmpty(min)) @@ -59,11 +61,11 @@ internal static partial class OpenApiV2Deserializer }, { "exclusiveMinimum", - (o, n, _) => o.IsExclusiveMinimum = bool.Parse(n.GetScalarValue()) + (o, n, _, c) => o.IsExclusiveMinimum = bool.Parse(n.GetScalarValue()!) }, { "maxLength", - (o, n, _) => + (o, n, _, c) => { var maxLength = n.GetScalarValue(); if (maxLength != null) @@ -74,7 +76,7 @@ internal static partial class OpenApiV2Deserializer }, { "minLength", - (o, n, _) => + (o, n, _, c) => { var minLength = n.GetScalarValue(); if (minLength != null) @@ -85,11 +87,11 @@ internal static partial class OpenApiV2Deserializer }, { "pattern", - (o, n, _) => o.Pattern = n.GetScalarValue() + (o, n, _, c) => o.Pattern = n.GetScalarValue() }, { "maxItems", - (o, n, _) => + (o, n, _, c) => { var maxItems = n.GetScalarValue(); if (maxItems != null) @@ -100,7 +102,7 @@ internal static partial class OpenApiV2Deserializer }, { "minItems", - (o, n, _) => + (o, n, _, c) => { var minItems = n.GetScalarValue(); if (minItems != null) @@ -111,7 +113,7 @@ internal static partial class OpenApiV2Deserializer }, { "uniqueItems", - (o, n, _) => + (o, n, _, c) => { var uniqueItems = n.GetScalarValue(); if (uniqueItems != null) @@ -122,7 +124,7 @@ internal static partial class OpenApiV2Deserializer }, { "maxProperties", - (o, n, _) => + (o, n, _, c) => { var maxProps = n.GetScalarValue(); if (maxProps != null) @@ -133,7 +135,7 @@ internal static partial class OpenApiV2Deserializer }, { "minProperties", - (o, n, _) => + (o, n, _, c) => { var minProps = n.GetScalarValue(); if (minProps != null) @@ -144,22 +146,21 @@ internal static partial class OpenApiV2Deserializer }, { "required", - (o, n, doc) => + (o, n, doc, c) => { o.Required = new HashSet( - n.CreateSimpleList((n2, p) => - n2.GetScalarValue(), doc) - .Where(s => s != null)!); + n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc, c) + .OfType()); } }, { "enum", - (o, n, _) => o.Enum = n.CreateListOfAny() + (o, n, _, c) => o.Enum = n.CreateListOfAny(c) }, { "type", - (o, n, _) => + (o, n, _, c) => { var type = n.GetScalarValue(); if (type != null) @@ -170,20 +171,20 @@ internal static partial class OpenApiV2Deserializer }, { "allOf", - (o, n, t) => o.AllOf = n.CreateList(LoadSchema, t) + (o, n, t, c) => o.AllOf = n.CreateList(LoadSchema, t, c) }, { "items", - (o, n, doc) => o.Items = LoadSchema(n, doc) + (o, n, doc, c) => o.Items = LoadSchema(n, doc, c) }, { "properties", - (o, n, t) => o.Properties = n.CreateMap(LoadSchema, t) + (o, n, t, c) => o.Properties = n.CreateMap(LoadSchema, t, c) }, { - "additionalProperties", (o, n, doc) => + "additionalProperties", (o, n, doc, c) => { - if (n is ValueNode) + if (n is JsonValue) { var value = n.GetScalarValue(); if (value is not null) @@ -193,24 +194,24 @@ internal static partial class OpenApiV2Deserializer } else { - o.AdditionalProperties = LoadSchema(n, doc); + o.AdditionalProperties = LoadSchema(n, doc, c); } } }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "format", - (o, n, _) => o.Format = n.GetScalarValue() + (o, n, _, c) => o.Format = n.GetScalarValue() }, { "default", - (o, n, _) => o.Default = n.CreateAny() + (o, n, _, c) => o.Default = n.CreateAny() }, { - "discriminator", (o, n, _) => + "discriminator", (o, n, _, c) => { o.Discriminator = new() { @@ -220,7 +221,7 @@ internal static partial class OpenApiV2Deserializer }, { "readOnly", - (o, n, _) => + (o, n, _, c) => { var readOnly = n.GetScalarValue(); if (readOnly is not null) @@ -231,32 +232,32 @@ internal static partial class OpenApiV2Deserializer }, { "xml", - (o, n, doc) => o.Xml = LoadXml(n, doc) + (o, n, doc, c) => o.Xml = LoadXml(n, doc, c) }, { "externalDocs", - (o, n, doc) => o.ExternalDocs = LoadExternalDocs(n, doc) + (o, n, doc, c) => o.ExternalDocs = LoadExternalDocs(n, doc, c) }, { "example", - (o, n, _) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n.CreateAny() }, { OpenApiConstants.PatternPropertiesExtension, - (o, n, t) => o.PatternProperties = n.CreateMap(LoadSchema, t) + (o, n, t, c) => o.PatternProperties = n.CreateMap(LoadSchema, t, c) }, }; private static readonly PatternFieldMap _openApiSchemaPatternFields = new PatternFieldMap { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiSchema LoadSchema(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiSchema LoadSchema(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("schema"); + var JsonObject = node.CheckMapNode("schema", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); @@ -265,10 +266,7 @@ public static IOpenApiSchema LoadSchema(ParseNode node, OpenApiDocument hostDocu var schema = new OpenApiSchema(); - foreach (var propertyNode in mapNode) - { - propertyNode.ParseField(schema, _openApiSchemaFixedFields, _openApiSchemaPatternFields, hostDocument); - } + ParseMap(JsonObject, schema, _openApiSchemaFixedFields, _openApiSchemaPatternFields, hostDocument, context); if (schema.Extensions is not null && schema.Extensions.ContainsKey(OpenApiConstants.NullableExtension)) { diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecurityRequirementDeserializer.cs index 51bf098e1..4c78198e8 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecurityRequirementDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System.Linq; namespace Microsoft.OpenApi.Reader.V2 @@ -11,19 +13,19 @@ namespace Microsoft.OpenApi.Reader.V2 /// internal static partial class OpenApiV2Deserializer { - public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiSecurityRequirement LoadSecurityRequirement(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("security"); + var JsonObject = node.CheckMapNode("security", context); var securityRequirement = new OpenApiSecurityRequirement(); - foreach (var property in mapNode) + foreach (var property in JsonObject) { var scheme = LoadSecuritySchemeByReference( hostDocument, - property.Name); + property.Key); - var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue(), hostDocument) + var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue(), hostDocument, context) .OfType() .ToList(); @@ -33,9 +35,9 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, } else { - mapNode.Context.Diagnostic.Errors.Add( - new(node.Context.GetLocation(), - $"Scheme {property.Name} is not found")); + context.Diagnostic.Errors.Add( + new(context.GetLocation(), + $"Scheme {property.Key} is not found")); } } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs index 3b6153901..b13eef794 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Linq; @@ -21,7 +23,7 @@ internal static partial class OpenApiV2Deserializer { { "type", - (o, n, _) => + (o, n, _, c) => { var type = n.GetScalarValue(); switch (type) @@ -40,16 +42,16 @@ internal static partial class OpenApiV2Deserializer break; default: - n.Context.Diagnostic.Errors.Add(new OpenApiError(n.Context.GetLocation(), $"Security scheme type {type} is not recognized.")); + c.Diagnostic.Errors.Add(new OpenApiError(c.GetLocation(), $"Security scheme type {type} is not recognized.")); break; } } }, - {"description", (o, n, _) => o.Description = n.GetScalarValue()}, - {"name", (o, n, _) => o.Name = n.GetScalarValue()}, - {"in", (o, n, _) => + {"description", (o, n, _, c) => o.Description = n.GetScalarValue()}, + {"name", (o, n, _, c) => o.Name = n.GetScalarValue()}, + {"in", (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var _in)) { return; } @@ -57,11 +59,11 @@ internal static partial class OpenApiV2Deserializer } }, { - "flow", (_, n, _) => _flowValue = n.GetScalarValue() + "flow", (_, n, _, c) => _flowValue = n.GetScalarValue() }, { "authorizationUrl", - (_, n, _) => + (_, n, _, c) => { var scalarValue = n.GetScalarValue(); if (_flow is not null && scalarValue is not null) @@ -72,7 +74,7 @@ internal static partial class OpenApiV2Deserializer }, { "tokenUrl", - (_, n, _) => + (_, n, _, c) => { var scalarValue = n.GetScalarValue(); if (_flow is not null && scalarValue is not null) @@ -82,11 +84,11 @@ internal static partial class OpenApiV2Deserializer } }, { - "scopes", (_, n, _) => + "scopes", (_, n, _, c) => { if (_flow is not null) { - _flow.Scopes = n.CreateSimpleMap(LoadString) + _flow.Scopes = n.CreateSimpleMap(LoadString, c) .Where(kv => kv.Value != null) .ToDictionary(kv => kv.Key, kv => kv.Value!); } @@ -97,23 +99,20 @@ internal static partial class OpenApiV2Deserializer private static readonly PatternFieldMap _securitySchemePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiSecurityScheme LoadSecurityScheme(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiSecurityScheme LoadSecurityScheme(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { // Reset the local variables every time this method is called. // TODO: Change _flow to a tempStorage variable to make the deserializer thread-safe. _flowValue = null; _flow = new(); - var mapNode = node.CheckMapNode("securityScheme"); + var JsonObject = node.CheckMapNode("securityScheme", context); var securityScheme = new OpenApiSecurityScheme(); - foreach (var property in mapNode) - { - property.ParseField(securityScheme, _securitySchemeFixedFields, _securitySchemePatternFields, hostDocument); - } + ParseMap(JsonObject, securityScheme, _securitySchemeFixedFields, _securitySchemePatternFields, hostDocument, context); // Put the Flow object in the right Flows property based on the string in "flow" if (_flowValue == OpenApiConstants.Implicit) diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiTagDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiTagDeserializer.cs index 1c57dc6c9..976632886 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiTagDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiTagDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V2 @@ -15,33 +17,30 @@ internal static partial class OpenApiV2Deserializer { { OpenApiConstants.Name, - (o, n, _) => o.Name = n.GetScalarValue() + (o, n, _, c) => o.Name = n.GetScalarValue() }, { OpenApiConstants.Description, - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { OpenApiConstants.ExternalDocs, - (o, n, t) => o.ExternalDocs = LoadExternalDocs(n, t) + (o, n, t, c) => o.ExternalDocs = LoadExternalDocs(n, t, c) } }; private static readonly PatternFieldMap _tagPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiTag LoadTag(ParseNode n, OpenApiDocument hostDocument) + public static OpenApiTag LoadTag(JsonNode n, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = n.CheckMapNode("tag"); + var JsonObject = n.CheckMapNode("tag", context); var domainObject = new OpenApiTag(); - foreach (var propertyNode in mapNode) - { - propertyNode.ParseField(domainObject, _tagFixedFields, _tagPatternFields, hostDocument); - } + ParseMap(JsonObject, domainObject, _tagFixedFields, _tagPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs index 80d079b5e..9bb20a3bb 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; @@ -14,39 +14,27 @@ namespace Microsoft.OpenApi.Reader.V2 internal static partial class OpenApiV2Deserializer { private static void ParseMap( - MapNode? mapNode, + JsonObject? jsonObject, T domainObject, FixedFieldMap fixedFieldMap, PatternFieldMap patternFieldMap, - OpenApiDocument doc) + OpenApiDocument doc, + ParsingContext context) { - if (mapNode == null) - { - return; - } - - var mapNodeFields = mapNode.ToDictionary(static x => x.Name, static x => x); - var allFields = fixedFieldMap.Keys.Union(mapNodeFields.Keys); - foreach (var propertyNodeName in allFields) - { - if (!mapNodeFields.TryGetValue(propertyNodeName, out var propertyNode)) - { - continue; - } - propertyNode.ParseField(domainObject, fixedFieldMap, patternFieldMap, doc); - } + jsonObject.ParseMap(domainObject, fixedFieldMap, patternFieldMap, doc, context); } private static void ProcessAnyFields( - MapNode mapNode, + JsonObject jsonObject, T domainObject, - AnyFieldMap anyFieldMap) + AnyFieldMap anyFieldMap, + ParsingContext context) { foreach (var anyFieldName in anyFieldMap.Keys.ToList()) { try { - mapNode.Context.StartObject(anyFieldName); + context.StartObject(anyFieldName); var anyFieldValue = anyFieldMap[anyFieldName].PropertyGetter(domainObject); if (anyFieldValue == null) @@ -60,24 +48,24 @@ private static void ProcessAnyFields( } catch (OpenApiException exception) { - exception.Pointer = mapNode.Context.GetLocation(); - mapNode.Context.Diagnostic.Errors.Add(new(exception)); + exception.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new(exception)); } finally { - mapNode.Context.EndObject(); + context.EndObject(); } } } - public static JsonNode LoadAny(ParseNode node, OpenApiDocument hostDocument) + public static JsonNode LoadAny(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { return node.CreateAny(); } - private static IOpenApiExtension LoadExtension(string name, ParseNode node) + private static IOpenApiExtension LoadExtension(string name, JsonNode node, ParsingContext context) { - if (node.Context.ExtensionParsers is not null && node.Context.ExtensionParsers.TryGetValue(name, out var parser)) + if (context.ExtensionParsers is not null && context.ExtensionParsers.TryGetValue(name, out var parser)) { try { @@ -85,15 +73,15 @@ private static IOpenApiExtension LoadExtension(string name, ParseNode node) } catch (OpenApiException ex) { - ex.Pointer = node.Context.GetLocation(); - node.Context.Diagnostic.Errors.Add(new(ex)); + ex.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new(ex)); } } return new JsonNodeExtension(node.CreateAny()); } - private static string? LoadString(ParseNode node) + private static string? LoadString(JsonNode node) { return node.GetScalarValue(); } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs index 9375683b2..ce54e4fcf 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Collections.Generic; @@ -20,7 +22,7 @@ public OpenApiV2VersionService(OpenApiDiagnostic diagnostic): base(diagnostic) { } - private readonly Dictionary> _loaders = new() + private readonly Dictionary> _loaders = new() { [typeof(JsonNodeExtension)] = OpenApiV2Deserializer.LoadAny, [typeof(OpenApiContact)] = OpenApiV2Deserializer.LoadContact, @@ -41,13 +43,13 @@ public OpenApiV2VersionService(OpenApiDiagnostic diagnostic): base(diagnostic) [typeof(OpenApiXml)] = OpenApiV2Deserializer.LoadXml }; - public override OpenApiDocument LoadDocument(RootNode rootNode, Uri location) + public override OpenApiDocument LoadDocument(JsonNode JsonNode, Uri location, ParsingContext context) { - return OpenApiV2Deserializer.LoadOpenApi(rootNode, location); + return OpenApiV2Deserializer.LoadOpenApi(JsonNode, location, context); } - internal override Dictionary> Loaders => _loaders; + internal override Dictionary> Loaders => _loaders; - public override string GetReferenceScalarValues(MapNode mapNode, string scalarValue) + public override string GetReferenceScalarValues(JsonObject JsonObject, string scalarValue) { throw new InvalidOperationException(); } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiXmlDeserializer.cs index c5034017d..a6c9cb430 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiXmlDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V2 @@ -15,10 +17,10 @@ internal static partial class OpenApiV2Deserializer { { "name", - (o, n, _) => o.Name = n.GetScalarValue() + (o, n, _, c) => o.Name = n.GetScalarValue() }, { - "namespace", (o, n, _) => + "namespace", (o, n, _, c) => { var scalarValue = n.GetScalarValue(); if (Uri.IsWellFormedUriString(scalarValue, UriKind.Absolute) && scalarValue is not null) @@ -33,11 +35,11 @@ internal static partial class OpenApiV2Deserializer }, { "prefix", - (o, n, _) => o.Prefix = n.GetScalarValue() + (o, n, _, c) => o.Prefix = n.GetScalarValue() }, { "attribute", - (o, n, _) => + (o, n, _, c) => { var attribute = n.GetScalarValue(); if (attribute is not null) @@ -50,7 +52,7 @@ internal static partial class OpenApiV2Deserializer }, { "wrapped", - (o, n, _) => + (o, n, _, c) => { var wrapped = n.GetScalarValue(); if (wrapped is not null) @@ -66,18 +68,15 @@ internal static partial class OpenApiV2Deserializer private static readonly PatternFieldMap _xmlPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiXml LoadXml(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiXml LoadXml(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("xml"); + var JsonObject = node.CheckMapNode("xml", context); var xml = new OpenApiXml(); - foreach (var property in mapNode) - { - property.ParseField(xml, _xmlFixedFields, _xmlPatternFields, hostDocument); - } + ParseMap(JsonObject, xml, _xmlFixedFields, _xmlPatternFields, hostDocument, context); return xml; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiCallbackDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiCallbackDeserializer.cs index 687113a8f..0e064a86f 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiCallbackDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiCallbackDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -16,15 +18,15 @@ internal static partial class OpenApiV3Deserializer private static readonly PatternFieldMap _callbackPatternFields = new() { - {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t) => o.AddPathItem(RuntimeExpression.Build(p), LoadPathItem(n, t))}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, + {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t, c) => o.AddPathItem(RuntimeExpression.Build(p), LoadPathItem(n, t, c))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))}, }; - public static IOpenApiCallback LoadCallback(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiCallback LoadCallback(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("callback"); + var JsonObject = node.CheckMapNode("callback", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { @@ -34,7 +36,7 @@ public static IOpenApiCallback LoadCallback(ParseNode node, OpenApiDocument host var domainObject = new OpenApiCallback(); - ParseMap(mapNode, domainObject, _callbackFixedFields, _callbackPatternFields, hostDocument); + ParseMap(JsonObject, domainObject, _callbackFixedFields, _callbackPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiComponentsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiComponentsDeserializer.cs index 516780ccb..b912bfbbc 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiComponentsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiComponentsDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -13,29 +15,29 @@ internal static partial class OpenApiV3Deserializer { private static readonly FixedFieldMap _componentsFixedFields = new() { - {"schemas", (o, n, t) => o.Schemas = n.CreateMap(LoadSchema, t)}, - {"responses", (o, n, t) => o.Responses = n.CreateMap(LoadResponse, t)}, - {"parameters", (o, n, t) => o.Parameters = n.CreateMap(LoadParameter, t)}, - {"examples", (o, n, t) => o.Examples = n.CreateMap(LoadExample, t)}, - {"requestBodies", (o, n, t) => o.RequestBodies = n.CreateMap(LoadRequestBody, t)}, - {"headers", (o, n, t) => o.Headers = n.CreateMap(LoadHeader, t)}, - {"securitySchemes", (o, n, t) => o.SecuritySchemes = n.CreateMap(LoadSecurityScheme, t)}, - {"links", (o, n, t) => o.Links = n.CreateMap(LoadLink, t)}, - {"callbacks", (o, n, t) => o.Callbacks = n.CreateMap(LoadCallback, t)} + {"schemas", (o, n, t, c) => o.Schemas = n.CreateMap(LoadSchema, t, c)}, + {"responses", (o, n, t, c) => o.Responses = n.CreateMap(LoadResponse, t, c)}, + {"parameters", (o, n, t, c) => o.Parameters = n.CreateMap(LoadParameter, t, c)}, + {"examples", (o, n, t, c) => o.Examples = n.CreateMap(LoadExample, t, c)}, + {"requestBodies", (o, n, t, c) => o.RequestBodies = n.CreateMap(LoadRequestBody, t, c)}, + {"headers", (o, n, t, c) => o.Headers = n.CreateMap(LoadHeader, t, c)}, + {"securitySchemes", (o, n, t, c) => o.SecuritySchemes = n.CreateMap(LoadSecurityScheme, t, c)}, + {"links", (o, n, t, c) => o.Links = n.CreateMap(LoadLink, t, c)}, + {"callbacks", (o, n, t, c) => o.Callbacks = n.CreateMap(LoadCallback, t, c)} }; private static readonly PatternFieldMap _componentsPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiComponents LoadComponents(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiComponents LoadComponents(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("components"); + var JsonObject = node.CheckMapNode("components", context); var components = new OpenApiComponents(); - ParseMap(mapNode, components, _componentsFixedFields, _componentsPatternFields, hostDocument); + ParseMap(JsonObject, components, _componentsFixedFields, _componentsPatternFields, hostDocument, context); return components; } } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiContactDeserializer.cs index 5c607c2dd..0e0a67323 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiContactDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,15 +17,15 @@ internal static partial class OpenApiV3Deserializer { { "name", - (o, n, _) => o.Name = n.GetScalarValue() + (o, n, _, c) => o.Name = n.GetScalarValue() }, { "email", - (o, n, _) => o.Email = n.GetScalarValue() + (o, n, _, c) => o.Email = n.GetScalarValue() }, { "url", - (o, n, t) => + (o, n, t, c) => { var url = n.GetScalarValue(); if (url != null) @@ -36,15 +38,15 @@ internal static partial class OpenApiV3Deserializer private static readonly PatternFieldMap _contactPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiContact LoadContact(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiContact LoadContact(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node as MapNode; + var JsonObject = node as JsonObject; var contact = new OpenApiContact(); - ParseMap(mapNode, contact, _contactFixedFields, _contactPatternFields, hostDocument); + ParseMap(JsonObject, contact, _contactFixedFields, _contactPatternFields, hostDocument, context); return contact; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs index 7d40df780..4deabffd1 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -16,29 +18,26 @@ internal static partial class OpenApiV3Deserializer { { "propertyName", - (o, n, _) => o.PropertyName = n.GetScalarValue() + (o, n, _, c) => o.PropertyName = n.GetScalarValue() }, { "mapping", - (o, n, doc) => o.Mapping = n.CreateSimpleMap((node) => LoadMapping(node, doc)) + (o, n, doc, c) => o.Mapping = n.CreateSimpleMap(node => LoadMapping(node, doc, c), c) } }; private static readonly PatternFieldMap _discriminatorPatternFields = new() {}; - public static OpenApiDiscriminator LoadDiscriminator(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiDiscriminator LoadDiscriminator(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("discriminator"); + var JsonObject = node.CheckMapNode("discriminator", context); var discriminator = new OpenApiDiscriminator(); - foreach (var property in mapNode) - { - property.ParseField(discriminator, _discriminatorFixedFields, _discriminatorPatternFields, hostDocument); - } + ParseMap(JsonObject, discriminator, _discriminatorFixedFields, _discriminatorPatternFields, hostDocument, context); return discriminator; } - public static OpenApiSchemaReference LoadMapping(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiSchemaReference LoadMapping(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { var pointer = node.GetScalarValue() ?? throw new InvalidOperationException("Could not get a pointer reference"); var reference = GetReferenceIdAndExternalResource(pointer); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs index 814957bee..46b841ecb 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Collections.Generic; @@ -16,23 +18,23 @@ internal static partial class OpenApiV3Deserializer private static readonly FixedFieldMap _openApiFixedFields = new() { { - "openapi", (_, _, _) => + "openapi", (_, _, _, c) => { } /* Version is valid field but we already parsed it */ }, - {"info", (o, n, _) => o.Info = LoadInfo(n, o)}, - {"servers", (o, n, _) => o.Servers = n.CreateList(LoadServer, o)}, - {"paths", (o, n, _) => o.Paths = LoadPaths(n, o)}, - {"components", (o, n, _) => o.Components = LoadComponents(n, o)}, - {"tags", (o, n, _) => { if (n.CreateList(LoadTag, o) is {Count:> 0} tags) {o.Tags = new HashSet(tags, OpenApiTagComparer.Instance); } } }, - {"externalDocs", (o, n, _) => o.ExternalDocs = LoadExternalDocs(n, o)}, - {"security", (o, n, _) => o.Security = n.CreateList(LoadSecurityRequirement, o)} + {"info", (o, n, _, c) => o.Info = LoadInfo(n, o, c)}, + {"servers", (o, n, _, c) => o.Servers = n.CreateList(LoadServer, o, c)}, + {"paths", (o, n, _, c) => o.Paths = LoadPaths(n, o, c)}, + {"components", (o, n, _, c) => o.Components = LoadComponents(n, o, c)}, + {"tags", (o, n, _, c) => { if (n.CreateList(LoadTag, o, c) is {Count:> 0} tags) {o.Tags = new HashSet(tags, OpenApiTagComparer.Instance); } } }, + {"externalDocs", (o, n, _, c) => o.ExternalDocs = LoadExternalDocs(n, o, c)}, + {"security", (o, n, _, c) => o.Security = n.CreateList(LoadSecurityRequirement, o, c)} }; private static readonly PatternFieldMap _openApiPatternFields = new PatternFieldMap { // We have no semantics to verify X- nodes, therefore treat them as just values. - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => { if (p.Equals("x-oai-$self", StringComparison.OrdinalIgnoreCase)) { @@ -44,20 +46,20 @@ internal static partial class OpenApiV3Deserializer } else { - o.AddExtension(p, LoadExtension(p, n)); + o.AddExtension(p, LoadExtension(p, n, c)); } }} }; - public static OpenApiDocument LoadOpenApi(RootNode rootNode, Uri location) + public static OpenApiDocument LoadOpenApi(JsonNode JsonNode, Uri location, ParsingContext context) { var openApiDoc = new OpenApiDocument { BaseUri = location }; - var openApiNode = rootNode.GetMap(); + var openApiNode = JsonNode.CheckMapNode("OpenAPI", context); - ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, openApiDoc); + ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, openApiDoc, context); // Register components openApiDoc.Workspace?.RegisterComponents(openApiDoc); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs index 5c3cc5a93..4df67861a 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,17 +17,17 @@ internal static partial class OpenApiV3Deserializer { { "contentType", - (o, n, _) => o.ContentType = n.GetScalarValue() + (o, n, _, c) => o.ContentType = n.GetScalarValue() }, { "headers", - (o, n, t) => o.Headers = n.CreateMap(LoadHeader, t) + (o, n, t, c) => o.Headers = n.CreateMap(LoadHeader, t, c) }, { "style", - (o, n, _) => + (o, n, _, c) => { - if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + if(!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var style)) { return; } @@ -34,7 +36,7 @@ internal static partial class OpenApiV3Deserializer }, { "explode", - (o, n, _) => + (o, n, _, c) => { var explode = n.GetScalarValue(); if (explode != null) @@ -45,7 +47,7 @@ internal static partial class OpenApiV3Deserializer }, { "allowReserved", - (o, n, _) => + (o, n, _, c) => { var allowReserved = n.GetScalarValue(); if (allowReserved != null) @@ -59,18 +61,15 @@ internal static partial class OpenApiV3Deserializer private static readonly PatternFieldMap _encodingPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiEncoding LoadEncoding(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiEncoding LoadEncoding(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("encoding"); + var JsonObject = node.CheckMapNode("encoding", context); var encoding = new OpenApiEncoding(); - foreach (var property in mapNode) - { - property.ParseField(encoding, _encodingFixedFields, _encodingPatternFields, hostDocument); - } + ParseMap(JsonObject, encoding, _encodingFixedFields, _encodingPatternFields, hostDocument, context); return encoding; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiExampleDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiExampleDeserializer.cs index d429098dd..a920b4072 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiExampleDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiExampleDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,35 +17,35 @@ internal static partial class OpenApiV3Deserializer { { "summary", - (o, n, _) => o.Summary = n.GetScalarValue() + (o, n, _, c) => o.Summary = n.GetScalarValue() }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "value", - (o, n, _) => o.Value = n.CreateAny() + (o, n, _, c) => o.Value = n.CreateAny() }, { "externalValue", - (o, n, _) => o.ExternalValue = n.GetScalarValue() + (o, n, _, c) => o.ExternalValue = n.GetScalarValue() }, }; private static readonly PatternFieldMap _examplePatternFields = new() { - {s => s.Equals("x-oai-dataValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.DataValue = n.CreateAny()}, - {s => s.Equals("x-oai-serializedValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.SerializedValue = n.GetScalarValue()}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.Equals("x-oai-dataValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.DataValue = n.CreateAny()}, + {s => s.Equals("x-oai-serializedValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.SerializedValue = n.GetScalarValue()}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiExample LoadExample(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiExample LoadExample(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("example"); + var JsonObject = node.CheckMapNode("example", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); @@ -51,10 +53,7 @@ public static IOpenApiExample LoadExample(ParseNode node, OpenApiDocument hostDo } var example = new OpenApiExample(); - foreach (var property in mapNode) - { - property.ParseField(example, _exampleFixedFields, _examplePatternFields, hostDocument); - } + ParseMap(JsonObject, example, _exampleFixedFields, _examplePatternFields, hostDocument, context); return example; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiExternalDocsDeserializer.cs index 04934520c..4f4399037 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiExternalDocsDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -17,11 +19,11 @@ internal static partial class OpenApiV3Deserializer // $ref { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "url", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -35,16 +37,16 @@ internal static partial class OpenApiV3Deserializer private static readonly PatternFieldMap _externalDocsPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiExternalDocs LoadExternalDocs(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiExternalDocs LoadExternalDocs(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("externalDocs"); + var JsonObject = node.CheckMapNode("externalDocs", context); var externalDocs = new OpenApiExternalDocs(); - ParseMap(mapNode, externalDocs, _externalDocsFixedFields, _externalDocsPatternFields, hostDocument); + ParseMap(JsonObject, externalDocs, _externalDocsFixedFields, _externalDocsPatternFields, hostDocument, context); return externalDocs; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs index 7ef6b2a0c..802d739d6 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,11 +17,11 @@ internal static partial class OpenApiV3Deserializer { { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "required", - (o, n, _) => + (o, n, _, c) => { var required = n.GetScalarValue(); if (required != null) @@ -30,7 +32,7 @@ internal static partial class OpenApiV3Deserializer }, { "deprecated", - (o, n, _) => + (o, n, _, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -41,7 +43,7 @@ internal static partial class OpenApiV3Deserializer }, { "allowEmptyValue", - (o, n, _) => + (o, n, _, c) => { var allowEmptyVal = n.GetScalarValue(); if (allowEmptyVal != null) @@ -52,7 +54,7 @@ internal static partial class OpenApiV3Deserializer }, { "allowReserved", - (o, n, _) => + (o, n, _, c) => { var allowReserved = n.GetScalarValue(); if (allowReserved != null) @@ -63,9 +65,9 @@ internal static partial class OpenApiV3Deserializer }, { "style", - (o, n, _) => + (o, n, _, c) => { - if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + if(!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var style)) { return; } @@ -74,7 +76,7 @@ internal static partial class OpenApiV3Deserializer }, { "explode", - (o, n, _) => + (o, n, _, c) => { var explode = n.GetScalarValue(); if (explode != null) @@ -85,34 +87,34 @@ internal static partial class OpenApiV3Deserializer }, { "schema", - (o, n, t) => o.Schema = LoadSchema(n, t) + (o, n, t, c) => o.Schema = LoadSchema(n, t, c) }, { - "content", (o, n, t) => + "content", (o, n, t, c) => { - o.Content = n.CreateMap(LoadMediaType, t); + o.Content = n.CreateMap(LoadMediaType, t, c); } }, { "examples", - (o, n, t) => o.Examples = n.CreateMap(LoadExample, t) + (o, n, t, c) => o.Examples = n.CreateMap(LoadExample, t, c) }, { "example", - (o, n, _) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n.CreateAny() }, }; private static readonly PatternFieldMap _headerPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiHeader LoadHeader(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiHeader LoadHeader(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("header"); + var JsonObject = node.CheckMapNode("header", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); @@ -120,10 +122,7 @@ public static IOpenApiHeader LoadHeader(ParseNode node, OpenApiDocument hostDocu } var header = new OpenApiHeader(); - foreach (var property in mapNode) - { - property.ParseField(header, _headerFixedFields, _headerPatternFields, hostDocument); - } + ParseMap(JsonObject, header, _headerFixedFields, _headerPatternFields, hostDocument, context); return header; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiInfoDeserializer.cs index fb4b0b27a..c76b25588 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiInfoDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,19 +17,19 @@ internal static partial class OpenApiV3Deserializer { { "title", - (o, n, _) => o.Title = n.GetScalarValue() + (o, n, _, c) => o.Title = n.GetScalarValue() }, { "version", - (o, n, _) => o.Version = n.GetScalarValue() + (o, n, _, c) => o.Version = n.GetScalarValue() }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "termsOfService", - (o, n, _) => + (o, n, _, c) => { var terms = n.GetScalarValue(); if (terms != null) @@ -38,24 +40,24 @@ internal static partial class OpenApiV3Deserializer }, { "contact", - (o, n, t) => o.Contact = LoadContact(n, t) + (o, n, t, c) => o.Contact = LoadContact(n, t, c) }, { "license", - (o, n, t) => o.License = LoadLicense(n, t) + (o, n, t, c) => o.License = LoadLicense(n, t, c) } }; public static readonly PatternFieldMap InfoPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, k, n, _) => o.AddExtension(k,LoadExtension(k, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, k, n, _, c) => o.AddExtension(k,LoadExtension(k, n, c))} }; - public static OpenApiInfo LoadInfo(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiInfo LoadInfo(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Info"); + var JsonObject = node.CheckMapNode("Info", context); var info = new OpenApiInfo(); - ParseMap(mapNode, info, InfoFixedFields, InfoPatternFields, hostDocument); + ParseMap(JsonObject, info, InfoFixedFields, InfoPatternFields, hostDocument, context); return info; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiLicenseDeserializer.cs index fda1443f3..6f8e98064 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiLicenseDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,11 +17,11 @@ internal static partial class OpenApiV3Deserializer { { "name", - (o, n, _) => o.Name = n.GetScalarValue() + (o, n, _, c) => o.Name = n.GetScalarValue() }, { "url", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -32,16 +34,16 @@ internal static partial class OpenApiV3Deserializer private static readonly PatternFieldMap _licensePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - internal static OpenApiLicense LoadLicense(ParseNode node, OpenApiDocument hostDocument) + internal static OpenApiLicense LoadLicense(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("License"); + var JsonObject = node.CheckMapNode("License", context); var license = new OpenApiLicense(); - ParseMap(mapNode, license, _licenseFixedFields, _licensePatternFields, hostDocument); + ParseMap(JsonObject, license, _licenseFixedFields, _licensePatternFields, hostDocument, context); return license; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiLinkDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiLinkDeserializer.cs index e6c08e221..c972ccc61 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiLinkDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiLinkDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,45 +17,45 @@ internal static partial class OpenApiV3Deserializer { { "operationRef", - (o, n, _) => o.OperationRef = n.GetScalarValue() + (o, n, _, c) => o.OperationRef = n.GetScalarValue() }, { "operationId", - (o, n, _) => o.OperationId = n.GetScalarValue() + (o, n, _, c) => o.OperationId = n.GetScalarValue() }, { "parameters", - (o, n, _) => o.Parameters = n.CreateSimpleMap(LoadRuntimeExpressionAnyWrapper) + (o, n, _, c) => o.Parameters = n.CreateSimpleMap(LoadRuntimeExpressionAnyWrapper, c) }, { "requestBody", - (o, n, _) => o.RequestBody = LoadRuntimeExpressionAnyWrapper(n) + (o, n, _, c) => o.RequestBody = LoadRuntimeExpressionAnyWrapper(n) }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, - {"server", (o, n, t) => o.Server = LoadServer(n, t)} + {"server", (o, n, t, c) => o.Server = LoadServer(n, t, c)} }; private static readonly PatternFieldMap _linkPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))}, }; - public static IOpenApiLink LoadLink(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiLink LoadLink(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("link"); + var JsonObject = node.CheckMapNode("link", context); var link = new OpenApiLink(); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); return new OpenApiLinkReference(reference.Item1, hostDocument, reference.Item2); } - ParseMap(mapNode, link, _linkFixedFields, _linkPatternFields, hostDocument); + ParseMap(JsonObject, link, _linkFixedFields, _linkPatternFields, hostDocument, context); return link; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs index ca334f4cb..a0af853ff 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -16,43 +18,43 @@ internal static partial class OpenApiV3Deserializer { { OpenApiConstants.Schema, - (o, n, t) => o.Schema = LoadSchema(n, t) + (o, n, t, c) => o.Schema = LoadSchema(n, t, c) }, { OpenApiConstants.Examples, - (o, n, t) => o.Examples = n.CreateMap(LoadExample, t) + (o, n, t, c) => o.Examples = n.CreateMap(LoadExample, t, c) }, { OpenApiConstants.Example, - (o, n, _) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n.CreateAny() }, { OpenApiConstants.Encoding, - (o, n, t) => o.Encoding = n.CreateMap(LoadEncoding, t) + (o, n, t, c) => o.Encoding = n.CreateMap(LoadEncoding, t, c) }, { OpenApiConstants.ExtensionFieldNamePrefix + "oai-" + OpenApiConstants.ItemEncoding, - (o, n, t) => o.ItemEncoding = LoadEncoding(n, t) + (o, n, t, c) => o.ItemEncoding = LoadEncoding(n, t, c) }, { OpenApiConstants.ExtensionFieldNamePrefix + "oai-" + OpenApiConstants.PrefixEncoding, - (o, n, t) => o.PrefixEncoding = n.CreateList(LoadEncoding, t) + (o, n, t, c) => o.PrefixEncoding = n.CreateList(LoadEncoding, t, c) }, }; private static readonly PatternFieldMap _mediaTypePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t) => + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t, c) => { // Handle x-oai-itemSchema as ItemSchema property for forward compatibility if (p.Equals("x-oai-itemSchema", StringComparison.OrdinalIgnoreCase)) { - o.ItemSchema = LoadSchema(n, t); + o.ItemSchema = LoadSchema(n, t, c); } else { - o.AddExtension(p, LoadExtension(p, n)); + o.AddExtension(p, LoadExtension(p, n, c)); } }} }; @@ -81,15 +83,15 @@ internal static partial class OpenApiV3Deserializer } }; - public static IOpenApiMediaType LoadMediaType(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiMediaType LoadMediaType(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode(OpenApiConstants.Content); + var JsonObject = node.CheckMapNode(OpenApiConstants.Content, context); var mediaType = new OpenApiMediaType(); - ParseMap(mapNode, mediaType, _mediaTypeFixedFields, _mediaTypePatternFields, hostDocument); + ParseMap(JsonObject, mediaType, _mediaTypeFixedFields, _mediaTypePatternFields, hostDocument, context); - ProcessAnyFields(mapNode, mediaType, _mediaTypeAnyFields); - ProcessAnyMapFields(mapNode, mediaType, _mediaTypeAnyMapOpenApiExampleFields); + ProcessAnyFields(JsonObject, mediaType, _mediaTypeAnyFields, context); + ProcessAnyMapFields(JsonObject, mediaType, _mediaTypeAnyMapOpenApiExampleFields, context); return mediaType; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowDeserializer.cs index 0ff7c74b7..f945b482a 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Linq; @@ -17,7 +19,7 @@ internal static partial class OpenApiV3Deserializer { { "authorizationUrl", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -28,7 +30,7 @@ internal static partial class OpenApiV3Deserializer }, { "tokenUrl", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -39,7 +41,7 @@ internal static partial class OpenApiV3Deserializer }, { "refreshUrl", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -48,13 +50,13 @@ internal static partial class OpenApiV3Deserializer } } }, - {"scopes", (o, n, _) => o.Scopes = n.CreateSimpleMap(LoadString).Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value!)} + {"scopes", (o, n, _, c) => o.Scopes = n.CreateSimpleMap(LoadString, c).Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value!)} }; private static readonly PatternFieldMap _oAuthFlowPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => { if (p.Equals("x-oai-deviceAuthorizationUrl", StringComparison.OrdinalIgnoreCase)) { @@ -66,20 +68,17 @@ internal static partial class OpenApiV3Deserializer } else { - o.AddExtension(p, LoadExtension(p, n)); + o.AddExtension(p, LoadExtension(p, n, c)); } }} }; - public static OpenApiOAuthFlow LoadOAuthFlow(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiOAuthFlow LoadOAuthFlow(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("OAuthFlow"); + var JsonObject = node.CheckMapNode("OAuthFlow", context); var oauthFlow = new OpenApiOAuthFlow(); - foreach (var property in mapNode) - { - property.ParseField(oauthFlow, _oAuthFlowFixedFields, _oAuthFlowPatternFields, hostDocument); - } + ParseMap(JsonObject, oauthFlow, _oAuthFlowFixedFields, _oAuthFlowPatternFields, hostDocument, context); return oauthFlow; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowsDeserializer.cs index 7c62177c0..14a764e05 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowsDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -14,28 +16,25 @@ internal static partial class OpenApiV3Deserializer private static readonly FixedFieldMap _oAuthFlowsFixedFields = new() { - {"implicit", (o, n, t) => o.Implicit = LoadOAuthFlow(n, t)}, - {"password", (o, n, t) => o.Password = LoadOAuthFlow(n, t)}, - {"clientCredentials", (o, n, t) => o.ClientCredentials = LoadOAuthFlow(n, t)}, - {"authorizationCode", (o, n, t) => o.AuthorizationCode = LoadOAuthFlow(n, t)} + {"implicit", (o, n, t, c) => o.Implicit = LoadOAuthFlow(n, t, c)}, + {"password", (o, n, t, c) => o.Password = LoadOAuthFlow(n, t, c)}, + {"clientCredentials", (o, n, t, c) => o.ClientCredentials = LoadOAuthFlow(n, t, c)}, + {"authorizationCode", (o, n, t, c) => o.AuthorizationCode = LoadOAuthFlow(n, t, c)} }; private static readonly PatternFieldMap _oAuthFlowsPatternFields = new() { - {s => s.Equals("x-oai-deviceAuthorization", StringComparison.OrdinalIgnoreCase), (o, p, n, t) => o.DeviceAuthorization = LoadOAuthFlow(n, t)}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.Equals("x-oai-deviceAuthorization", StringComparison.OrdinalIgnoreCase), (o, p, n, t, c) => o.DeviceAuthorization = LoadOAuthFlow(n, t, c)}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiOAuthFlows LoadOAuthFlows(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiOAuthFlows LoadOAuthFlows(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("OAuthFlows"); + var JsonObject = node.CheckMapNode("OAuthFlows", context); var oAuthFlows = new OpenApiOAuthFlows(); - foreach (var property in mapNode) - { - property.ParseField(oAuthFlows, _oAuthFlowsFixedFields, _oAuthFlowsPatternFields, hostDocument); - } + ParseMap(JsonObject, oAuthFlows, _oAuthFlowsFixedFields, _oAuthFlowsPatternFields, hostDocument, context); return oAuthFlows; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiOperationDeserializer.cs index ae0c0e322..0c99b3332 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiOperationDeserializer.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; @@ -18,16 +18,17 @@ internal static partial class OpenApiV3Deserializer new() { { - "tags", (o, n, doc) => { + "tags", (o, n, doc, c) => { if (n.CreateSimpleList( - (valueNode, doc) => + (jsonNode, document) => { - var val = valueNode.GetScalarValue(); + var val = jsonNode.GetScalarValue(); if (string.IsNullOrEmpty(val)) return null; // Avoid exception on empty tag, we'll remove these from the list further on - return LoadTagByReference(val , doc); - }, - doc) + return LoadTagByReference(val!, document); + }, + doc, + c) // Filter out empty tags instead of excepting on them .OfType().ToList() is {Count: > 0} tags) { @@ -37,39 +38,39 @@ internal static partial class OpenApiV3Deserializer }, { "summary", - (o, n, _) => o.Summary = n.GetScalarValue() + (o, n, _, c) => o.Summary = n.GetScalarValue() }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "externalDocs", - (o, n, doc) => o.ExternalDocs = LoadExternalDocs(n, doc) + (o, n, doc, c) => o.ExternalDocs = LoadExternalDocs(n, doc, c) }, { "operationId", - (o, n, _) => o.OperationId = n.GetScalarValue() + (o, n, _, c) => o.OperationId = n.GetScalarValue() }, { "parameters", - (o, n, t) => o.Parameters = n.CreateList(LoadParameter, t) + (o, n, t, c) => o.Parameters = n.CreateList(LoadParameter, t, c) }, { "requestBody", - (o, n, t) => o.RequestBody = LoadRequestBody(n, t) + (o, n, t, c) => o.RequestBody = LoadRequestBody(n, t, c) }, { "responses", - (o, n, t) => o.Responses = LoadResponses(n, t) + (o, n, t, c) => o.Responses = LoadResponses(n, t, c) }, { "callbacks", - (o, n, t) => o.Callbacks = n.CreateMap(LoadCallback, t) + (o, n, t, c) => o.Callbacks = n.CreateMap(LoadCallback, t, c) }, { "deprecated", - (o, n, _) => + (o, n, _, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -80,33 +81,33 @@ internal static partial class OpenApiV3Deserializer }, { "security", - (o, n, t) => + (o, n, t, c) => { - if (n.JsonNode is JsonArray) + if (n is JsonArray) { - o.Security = n.CreateList(LoadSecurityRequirement, t); + o.Security = n.CreateList(LoadSecurityRequirement, t, c); } } }, { "servers", - (o, n, t) => o.Servers = n.CreateList(LoadServer, t) + (o, n, t, c) => o.Servers = n.CreateList(LoadServer, t, c) }, }; private static readonly PatternFieldMap _operationPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))}, }; - internal static OpenApiOperation LoadOperation(ParseNode node, OpenApiDocument hostDocument) + internal static OpenApiOperation LoadOperation(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Operation"); + var JsonObject = node.CheckMapNode("Operation", context); var operation = new OpenApiOperation(); - ParseMap(mapNode, operation, _operationFixedFields, _operationPatternFields, hostDocument); + ParseMap(JsonObject, operation, _operationFixedFields, _operationPatternFields, hostDocument, context); return operation; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs index 33f4d32aa..b740360cc 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -16,12 +18,12 @@ internal static partial class OpenApiV3Deserializer { { "name", - (o, n,_) => o.Name = n.GetScalarValue() + (o, n, _, c) => o.Name = n.GetScalarValue() }, { - "in", (o, n, _) => + "in", (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var _in)) { return; } @@ -30,11 +32,11 @@ internal static partial class OpenApiV3Deserializer }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "required", - (o, n, t) => + (o, n, t, c) => { var required = n.GetScalarValue(); if (required != null) @@ -45,7 +47,7 @@ internal static partial class OpenApiV3Deserializer }, { "deprecated", - (o, n, t) => + (o, n, t, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -56,7 +58,7 @@ internal static partial class OpenApiV3Deserializer }, { "allowEmptyValue", - (o, n, t) => + (o, n, t, c) => { var allowEmptyValue = n.GetScalarValue(); if (allowEmptyValue != null) @@ -67,7 +69,7 @@ internal static partial class OpenApiV3Deserializer }, { "allowReserved", - (o, n, _) => + (o, n, _, c) => { var allowReserved = n.GetScalarValue(); if (allowReserved != null) @@ -78,9 +80,9 @@ internal static partial class OpenApiV3Deserializer }, { "style", - (o, n, _) => + (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var style)) { return; } @@ -89,7 +91,7 @@ internal static partial class OpenApiV3Deserializer }, { "explode", - (o, n, _) => + (o, n, _, c) => { var explode = n.GetScalarValue(); if (explode != null) @@ -100,26 +102,26 @@ internal static partial class OpenApiV3Deserializer }, { "schema", - (o, n, t) => o.Schema = LoadSchema(n, t) + (o, n, t, c) => o.Schema = LoadSchema(n, t, c) }, { "content", - (o, n, t) => o.Content = n.CreateMap(LoadMediaType, t) + (o, n, t, c) => o.Content = n.CreateMap(LoadMediaType, t, c) }, { "examples", - (o, n, t) => o.Examples = n.CreateMap(LoadExample, t) + (o, n, t, c) => o.Examples = n.CreateMap(LoadExample, t, c) }, { "example", - (o, n, _) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n.CreateAny() }, }; private static readonly PatternFieldMap _parameterPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; private static readonly AnyFieldMap _parameterAnyFields = new() @@ -146,11 +148,11 @@ internal static partial class OpenApiV3Deserializer } }; - public static IOpenApiParameter LoadParameter(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiParameter LoadParameter(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("parameter"); + var JsonObject = node.CheckMapNode("parameter", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); @@ -159,9 +161,9 @@ public static IOpenApiParameter LoadParameter(ParseNode node, OpenApiDocument ho var parameter = new OpenApiParameter(); - ParseMap(mapNode, parameter, _parameterFixedFields, _parameterPatternFields, hostDocument); - ProcessAnyFields(mapNode, parameter, _parameterAnyFields); - ProcessAnyMapFields(mapNode, parameter, _parameterAnyMapOpenApiExampleFields); + ParseMap(JsonObject, parameter, _parameterFixedFields, _parameterPatternFields, hostDocument, context); + ProcessAnyFields(JsonObject, parameter, _parameterAnyFields, context); + ProcessAnyMapFields(JsonObject, parameter, _parameterAnyMapOpenApiExampleFields, context); return parameter; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiPathItemDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiPathItemDeserializer.cs index 45f525484..f55abfe25 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiPathItemDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiPathItemDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Net.Http; @@ -16,39 +18,39 @@ internal static partial class OpenApiV3Deserializer { { "summary", - (o, n, _) => o.Summary = n.GetScalarValue() + (o, n, _, c) => o.Summary = n.GetScalarValue() }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, - {"get", (o, n, t) => o.AddOperation(HttpMethod.Get, LoadOperation(n, t))}, - {"put", (o, n, t) => o.AddOperation(HttpMethod.Put, LoadOperation(n, t))}, - {"post", (o, n, t) => o.AddOperation(HttpMethod.Post, LoadOperation(n, t))}, - {"delete", (o, n, t) => o.AddOperation(HttpMethod.Delete, LoadOperation(n, t))}, - {"options", (o, n, t) => o.AddOperation(HttpMethod.Options, LoadOperation(n, t))}, - {"head", (o, n, t) => o.AddOperation(HttpMethod.Head, LoadOperation(n, t))}, + {"get", (o, n, t, c) => o.AddOperation(HttpMethod.Get, LoadOperation(n, t, c))}, + {"put", (o, n, t, c) => o.AddOperation(HttpMethod.Put, LoadOperation(n, t, c))}, + {"post", (o, n, t, c) => o.AddOperation(HttpMethod.Post, LoadOperation(n, t, c))}, + {"delete", (o, n, t, c) => o.AddOperation(HttpMethod.Delete, LoadOperation(n, t, c))}, + {"options", (o, n, t, c) => o.AddOperation(HttpMethod.Options, LoadOperation(n, t, c))}, + {"head", (o, n, t, c) => o.AddOperation(HttpMethod.Head, LoadOperation(n, t, c))}, #if NETSTANDARD2_1_OR_GREATER - {"patch", (o, n, t) => o.AddOperation(HttpMethod.Patch, LoadOperation(n, t))}, + {"patch", (o, n, t, c) => o.AddOperation(HttpMethod.Patch, LoadOperation(n, t, c))}, #else - {"patch", (o, n, t) => o.AddOperation(new HttpMethod("PATCH"), LoadOperation(n, t))}, + {"patch", (o, n, t, c) => o.AddOperation(new HttpMethod("PATCH"), LoadOperation(n, t, c))}, #endif - {"trace", (o, n, t) => o.AddOperation(HttpMethod.Trace, LoadOperation(n, t))}, - {"servers", (o, n, t) => o.Servers = n.CreateList(LoadServer, t)}, - {"parameters", (o, n, t) => o.Parameters = n.CreateList(LoadParameter, t)} + {"trace", (o, n, t, c) => o.AddOperation(HttpMethod.Trace, LoadOperation(n, t, c))}, + {"servers", (o, n, t, c) => o.Servers = n.CreateList(LoadServer, t, c)}, + {"parameters", (o, n, t, c) => o.Parameters = n.CreateList(LoadParameter, t, c)} }; private static readonly PatternFieldMap _pathItemPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiPathItem LoadPathItem(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiPathItem LoadPathItem(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("PathItem"); + var JsonObject = node.CheckMapNode("PathItem", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); @@ -57,7 +59,7 @@ public static IOpenApiPathItem LoadPathItem(ParseNode node, OpenApiDocument host var pathItem = new OpenApiPathItem(); - ParseMap(mapNode, pathItem, _pathItemFixedFields, _pathItemPatternFields, hostDocument); + ParseMap(JsonObject, pathItem, _pathItemFixedFields, _pathItemPatternFields, hostDocument, context); return pathItem; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiPathsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiPathsDeserializer.cs index 066812171..5292d74ca 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiPathsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiPathsDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,17 +17,17 @@ internal static partial class OpenApiV3Deserializer private static readonly PatternFieldMap _pathsPatternFields = new() { - {s => s.StartsWith("/", StringComparison.OrdinalIgnoreCase), (o, k, n, t) => o.Add(k, LoadPathItem(n, t))}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith("/", StringComparison.OrdinalIgnoreCase), (o, k, n, t, c) => o.Add(k, LoadPathItem(n, t, c))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiPaths LoadPaths(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiPaths LoadPaths(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Paths"); + var JsonObject = node.CheckMapNode("Paths", context); var domainObject = new OpenApiPaths(); - ParseMap(mapNode, domainObject, _pathsFixedFields, _pathsPatternFields, hostDocument); + ParseMap(JsonObject, domainObject, _pathsFixedFields, _pathsPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiRequestBodyDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiRequestBodyDeserializer.cs index 9a88d9d1c..f3c634911 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiRequestBodyDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiRequestBodyDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -16,15 +18,15 @@ internal static partial class OpenApiV3Deserializer { { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "content", - (o, n, t) => o.Content = n.CreateMap(LoadMediaType, t) + (o, n, t, c) => o.Content = n.CreateMap(LoadMediaType, t, c) }, { "required", - (o, n, _) => + (o, n, _, c) => { var required = n.GetScalarValue(); if (required != null) @@ -38,14 +40,14 @@ internal static partial class OpenApiV3Deserializer private static readonly PatternFieldMap _requestBodyPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiRequestBody LoadRequestBody(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiRequestBody LoadRequestBody(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("requestBody"); + var JsonObject = node.CheckMapNode("requestBody", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); @@ -53,10 +55,7 @@ public static IOpenApiRequestBody LoadRequestBody(ParseNode node, OpenApiDocumen } var requestBody = new OpenApiRequestBody(); - foreach (var property in mapNode) - { - property.ParseField(requestBody, _requestBodyFixedFields, _requestBodyPatternFields, hostDocument); - } + ParseMap(JsonObject, requestBody, _requestBodyFixedFields, _requestBodyPatternFields, hostDocument, context); return requestBody; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiResponseDeserializer.cs index d251a1992..81bdb16c2 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiResponseDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,26 +17,26 @@ internal static partial class OpenApiV3Deserializer { { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "headers", - (o, n, t) => o.Headers = n.CreateMap(LoadHeader, t) + (o, n, t, c) => o.Headers = n.CreateMap(LoadHeader, t, c) }, { "content", - (o, n, t) => o.Content = n.CreateMap(LoadMediaType, t) + (o, n, t, c) => o.Content = n.CreateMap(LoadMediaType, t, c) }, { "links", - (o, n, t) => o.Links = n.CreateMap(LoadLink, t) + (o, n, t, c) => o.Links = n.CreateMap(LoadLink, t, c) } }; private static readonly PatternFieldMap _responsePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => { if (p.Equals("x-oai-summary", StringComparison.OrdinalIgnoreCase)) { @@ -42,16 +44,16 @@ internal static partial class OpenApiV3Deserializer } else { - o.AddExtension(p, LoadExtension(p,n)); + o.AddExtension(p, LoadExtension(p, n, c)); } }} }; - public static IOpenApiResponse LoadResponse(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiResponse LoadResponse(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("response"); + var JsonObject = node.CheckMapNode("response", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); @@ -59,7 +61,7 @@ public static IOpenApiResponse LoadResponse(ParseNode node, OpenApiDocument host } var response = new OpenApiResponse(); - ParseMap(mapNode, response, _responseFixedFields, _responsePatternFields, hostDocument); + ParseMap(JsonObject, response, _responseFixedFields, _responsePatternFields, hostDocument, context); return response; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiResponsesDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiResponsesDeserializer.cs index 697312f30..94fa924e0 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiResponsesDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiResponsesDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,17 +17,17 @@ internal static partial class OpenApiV3Deserializer public static readonly PatternFieldMap ResponsesPatternFields = new() { - {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t) => o.Add(p, LoadResponse(n, t))}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t, c) => o.Add(p, LoadResponse(n, t, c))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiResponses LoadResponses(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiResponses LoadResponses(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Responses"); + var JsonObject = node.CheckMapNode("Responses", context); var domainObject = new OpenApiResponses(); - ParseMap(mapNode, domainObject, ResponsesFixedFields, ResponsesPatternFields, hostDocument); + ParseMap(JsonObject, domainObject, ResponsesFixedFields, ResponsesPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs index 804c8567e..096e6e564 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Collections.Generic; using System.Globalization; @@ -18,11 +20,11 @@ internal static partial class OpenApiV3Deserializer { { "title", - (o, n, _) => o.Title = n.GetScalarValue() + (o, n, _, c) => o.Title = n.GetScalarValue() }, { "multipleOf", - (o, n, _) => + (o, n, _, c) => { var multipleOf = n.GetScalarValue(); if (multipleOf != null) @@ -33,7 +35,7 @@ internal static partial class OpenApiV3Deserializer }, { "maximum", - (o, n,_) => + (o, n, _, c) => { var max = n.GetScalarValue(); if (!string.IsNullOrEmpty(max)) @@ -44,11 +46,11 @@ internal static partial class OpenApiV3Deserializer }, { "exclusiveMaximum", - (o, n, _) => o.IsExclusiveMaximum = bool.Parse(n.GetScalarValue()) + (o, n, _, c) => o.IsExclusiveMaximum = bool.Parse(n.GetScalarValue()!) }, { "minimum", - (o, n, _) => + (o, n, _, c) => { var min = n.GetScalarValue(); if (!string.IsNullOrEmpty(min)) @@ -59,11 +61,11 @@ internal static partial class OpenApiV3Deserializer }, { "exclusiveMinimum", - (o, n, _) => o.IsExclusiveMinimum = bool.Parse(n.GetScalarValue()) + (o, n, _, c) => o.IsExclusiveMinimum = bool.Parse(n.GetScalarValue()!) }, { "maxLength", - (o, n, _) => + (o, n, _, c) => { var maxLength = n.GetScalarValue(); if (maxLength != null) @@ -74,7 +76,7 @@ internal static partial class OpenApiV3Deserializer }, { "minLength", - (o, n, _) => + (o, n, _, c) => { var minLength = n.GetScalarValue(); if (minLength != null) @@ -85,11 +87,11 @@ internal static partial class OpenApiV3Deserializer }, { "pattern", - (o, n, _) => o.Pattern = n.GetScalarValue() + (o, n, _, c) => o.Pattern = n.GetScalarValue() }, { "maxItems", - (o, n, _) => + (o, n, _, c) => { var maxItems = n.GetScalarValue(); if (maxItems != null) @@ -100,7 +102,7 @@ internal static partial class OpenApiV3Deserializer }, { "minItems", - (o, n, _) => + (o, n, _, c) => { var minItems = n.GetScalarValue(); if (minItems != null) @@ -111,7 +113,7 @@ internal static partial class OpenApiV3Deserializer }, { "uniqueItems", - (o, n, _) => + (o, n, _, c) => { var uniqueItems = n.GetScalarValue(); if (uniqueItems != null) @@ -122,7 +124,7 @@ internal static partial class OpenApiV3Deserializer }, { "maxProperties", - (o, n, _) => + (o, n, _, c) => { var maxProps = n.GetScalarValue(); if (maxProps != null) @@ -133,7 +135,7 @@ internal static partial class OpenApiV3Deserializer }, { "minProperties", - (o, n, _) => + (o, n, _, c) => { var minProps = n.GetScalarValue(); if (minProps != null) @@ -144,15 +146,15 @@ internal static partial class OpenApiV3Deserializer }, { "required", - (o, n, doc) => o.Required = new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc).Where(s => s != null)) + (o, n, doc, c) => o.Required = new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc, c).OfType()) }, { "enum", - (o, n, _) => o.Enum = n.CreateListOfAny() + (o, n, _, c) => o.Enum = n.CreateListOfAny(c) }, { "type", - (o, n, _) => { + (o, n, _, c) => { var type = n.GetScalarValue()?.ToJsonSchemaType(); // so we don't lose the value from nullable if (o.Type.HasValue) @@ -163,32 +165,32 @@ internal static partial class OpenApiV3Deserializer }, { "allOf", - (o, n, t) => o.AllOf = n.CreateList(LoadSchema, t) + (o, n, t, c) => o.AllOf = n.CreateList(LoadSchema, t, c) }, { "oneOf", - (o, n, doc) => o.OneOf = n.CreateList(LoadSchema, doc) + (o, n, doc, c) => o.OneOf = n.CreateList(LoadSchema, doc, c) }, { "anyOf", - (o, n, t) => o.AnyOf = n.CreateList(LoadSchema, t) + (o, n, t, c) => o.AnyOf = n.CreateList(LoadSchema, t, c) }, { "not", - (o, n, doc) => o.Not = LoadSchema(n, doc) + (o, n, doc, c) => o.Not = LoadSchema(n, doc, c) }, { "items", - (o, n, doc) => o.Items = LoadSchema(n, doc) + (o, n, doc, c) => o.Items = LoadSchema(n, doc, c) }, { "properties", - (o, n, t) => o.Properties = n.CreateMap(LoadSchema, t) + (o, n, t, c) => o.Properties = n.CreateMap(LoadSchema, t, c) }, { - "additionalProperties", (o, n, doc) => + "additionalProperties", (o, n, doc, c) => { - if (n is ValueNode) + if (n is JsonValue) { var value = n.GetScalarValue(); if (value is not null) @@ -198,25 +200,25 @@ internal static partial class OpenApiV3Deserializer } else { - o.AdditionalProperties = LoadSchema(n, doc); + o.AdditionalProperties = LoadSchema(n, doc, c); } } }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "format", - (o, n, _) => o.Format = n.GetScalarValue() + (o, n, _, c) => o.Format = n.GetScalarValue() }, { "default", - (o, n, _) => o.Default = n.CreateAny() + (o, n, _, c) => o.Default = n.CreateAny() }, { "nullable", - (o, n, _) => + (o, n, _, c) => { if (bool.TryParse(n.GetScalarValue(), out var parsed) && parsed) { @@ -229,11 +231,11 @@ internal static partial class OpenApiV3Deserializer }, { "discriminator", - (o, n, doc) => o.Discriminator = LoadDiscriminator(n, doc) + (o, n, doc, c) => o.Discriminator = LoadDiscriminator(n, doc, c) }, { "readOnly", - (o, n, _) => + (o, n, _, c) => { var readOnly = n.GetScalarValue(); if (readOnly != null) @@ -244,7 +246,7 @@ internal static partial class OpenApiV3Deserializer }, { "writeOnly", - (o, n, _) => + (o, n, _, c) => { var writeOnly = n.GetScalarValue(); if (writeOnly != null) @@ -255,19 +257,19 @@ internal static partial class OpenApiV3Deserializer }, { "xml", - (o, n, doc) => o.Xml = LoadXml(n, doc) + (o, n, doc, c) => o.Xml = LoadXml(n, doc, c) }, { "externalDocs", - (o, n, doc) => o.ExternalDocs = LoadExternalDocs(n, doc) + (o, n, doc, c) => o.ExternalDocs = LoadExternalDocs(n, doc, c) }, { "example", - (o, n, _) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n.CreateAny() }, { "deprecated", - (o, n, t) => + (o, n, t, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -278,20 +280,20 @@ internal static partial class OpenApiV3Deserializer }, { OpenApiConstants.PatternPropertiesExtension, - (o, n, t) => o.PatternProperties = n.CreateMap(LoadSchema, t) + (o, n, t, c) => o.PatternProperties = n.CreateMap(LoadSchema, t, c) }, }; private static readonly PatternFieldMap _openApiSchemaPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiSchema LoadSchema(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiSchema LoadSchema(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode(OpenApiConstants.Schema); + var JsonObject = node.CheckMapNode(OpenApiConstants.Schema, context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { @@ -301,10 +303,7 @@ public static IOpenApiSchema LoadSchema(ParseNode node, OpenApiDocument hostDocu var schema = new OpenApiSchema(); - foreach (var propertyNode in mapNode) - { - propertyNode.ParseField(schema, _openApiSchemaFixedFields, _openApiSchemaPatternFields, hostDocument); - } + ParseMap(JsonObject, schema, _openApiSchemaFixedFields, _openApiSchemaPatternFields, hostDocument, context); if (schema.Extensions is not null && schema.Extensions.ContainsKey(OpenApiConstants.NullableExtension)) { diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecurityRequirementDeserializer.cs index a102f4e84..859f5a1aa 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecurityRequirementDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System.Linq; namespace Microsoft.OpenApi.Reader.V3 @@ -11,17 +13,17 @@ namespace Microsoft.OpenApi.Reader.V3 /// internal static partial class OpenApiV3Deserializer { - public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiSecurityRequirement LoadSecurityRequirement(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("security"); + var JsonObject = node.CheckMapNode("security", context); var securityRequirement = new OpenApiSecurityRequirement(); - foreach (var property in mapNode) + foreach (var property in JsonObject) { - var scheme = LoadSecuritySchemeByReference(hostDocument, property.Name); + var scheme = LoadSecuritySchemeByReference(hostDocument, property.Key); - var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue(), hostDocument) + var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue(), hostDocument, context) .OfType() .ToList(); @@ -31,8 +33,8 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, } else { - mapNode.Context.Diagnostic.Errors.Add( - new(node.Context.GetLocation(), $"Scheme {property.Name} is not found")); + context.Diagnostic.Errors.Add( + new(context.GetLocation(), $"Scheme {property.Key} is not found")); } } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs index d0cbeb3ab..a8057bfc3 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -16,9 +18,9 @@ internal static partial class OpenApiV3Deserializer { { "type", - (o, n, _) => + (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var type)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var type)) { return; } @@ -27,17 +29,17 @@ internal static partial class OpenApiV3Deserializer }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "name", - (o, n, _) => o.Name = n.GetScalarValue() + (o, n, _, c) => o.Name = n.GetScalarValue() }, { "in", - (o, n, _) => + (o, n, _, c) => { - if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) + if(!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var _in)) { return; } @@ -46,15 +48,15 @@ internal static partial class OpenApiV3Deserializer }, { "scheme", - (o, n, _) => o.Scheme = n.GetScalarValue() + (o, n, _, c) => o.Scheme = n.GetScalarValue() }, { "bearerFormat", - (o, n, _) => o.BearerFormat = n.GetScalarValue() + (o, n, _, c) => o.BearerFormat = n.GetScalarValue() }, { "openIdConnectUrl", - (o, n, _) => + (o, n, _, c) => { var connectUrl = n.GetScalarValue(); if (connectUrl != null) @@ -65,14 +67,14 @@ internal static partial class OpenApiV3Deserializer }, { "flows", - (o, n, t) => o.Flows = LoadOAuthFlows(n, t) + (o, n, t, c) => o.Flows = LoadOAuthFlows(n, t, c) } }; private static readonly PatternFieldMap _securitySchemePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => { if (p.Equals("x-oai-deprecated", StringComparison.OrdinalIgnoreCase)) { @@ -84,15 +86,15 @@ internal static partial class OpenApiV3Deserializer } else { - o.AddExtension(p, LoadExtension(p,n)); + o.AddExtension(p, LoadExtension(p, n, c)); } }} }; - public static IOpenApiSecurityScheme LoadSecurityScheme(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiSecurityScheme LoadSecurityScheme(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("securityScheme"); - var pointer = mapNode.GetReferencePointer(); + var JsonObject = node.CheckMapNode("securityScheme", context); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); @@ -100,10 +102,7 @@ public static IOpenApiSecurityScheme LoadSecurityScheme(ParseNode node, OpenApiD } var securityScheme = new OpenApiSecurityScheme(); - foreach (var property in mapNode) - { - property.ParseField(securityScheme, _securitySchemeFixedFields, _securitySchemePatternFields, hostDocument); - } + ParseMap(JsonObject, securityScheme, _securitySchemeFixedFields, _securitySchemePatternFields, hostDocument, context); return securityScheme; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiServerDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiServerDeserializer.cs index 91c3d3e9a..0bb3f0f25 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiServerDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiServerDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,21 +17,21 @@ internal static partial class OpenApiV3Deserializer { { "url", - (o, n, _) => o.Url = n.GetScalarValue() + (o, n, _, c) => o.Url = n.GetScalarValue() }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "variables", - (o, n, t) => o.Variables = n.CreateMap(LoadServerVariable, t) + (o, n, t, c) => o.Variables = n.CreateMap(LoadServerVariable, t, c) } }; private static readonly PatternFieldMap _serverPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => { if (p.Equals("x-oai-name", StringComparison.OrdinalIgnoreCase)) { @@ -37,18 +39,18 @@ internal static partial class OpenApiV3Deserializer } else { - o.AddExtension(p, LoadExtension(p,n)); + o.AddExtension(p, LoadExtension(p, n, c)); } }} }; - public static OpenApiServer LoadServer(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiServer LoadServer(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("server"); + var JsonObject = node.CheckMapNode("server", context); var server = new OpenApiServer(); - ParseMap(mapNode, server, _serverFixedFields, _serverPatternFields, hostDocument); + ParseMap(JsonObject, server, _serverFixedFields, _serverPatternFields, hostDocument, context); return server; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiServerVariableDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiServerVariableDeserializer.cs index a74a3a1f0..152e4a6f4 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiServerVariableDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiServerVariableDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Linq; @@ -17,31 +19,31 @@ internal static partial class OpenApiV3Deserializer { { "enum", - (o, n, doc) => o.Enum = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc).OfType().ToList() + (o, n, doc, c) => o.Enum = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc, c).OfType().ToList() }, { "default", - (o, n, _) => o.Default = n.GetScalarValue() + (o, n, _, c) => o.Default = n.GetScalarValue() }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, }; private static readonly PatternFieldMap _serverVariablePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiServerVariable LoadServerVariable(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiServerVariable LoadServerVariable(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("serverVariable"); + var JsonObject = node.CheckMapNode("serverVariable", context); var serverVariable = new OpenApiServerVariable(); - ParseMap(mapNode, serverVariable, _serverVariableFixedFields, _serverVariablePatternFields, hostDocument); + ParseMap(JsonObject, serverVariable, _serverVariableFixedFields, _serverVariablePatternFields, hostDocument, context); return serverVariable; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiTagDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiTagDeserializer.cs index 7e53533ed..4f528d346 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiTagDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiTagDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,15 +17,15 @@ internal static partial class OpenApiV3Deserializer { { OpenApiConstants.Name, - (o, n, _) => o.Name = n.GetScalarValue() + (o, n, _, c) => o.Name = n.GetScalarValue() }, { OpenApiConstants.Description, - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { OpenApiConstants.ExternalDocs, - (o, n, t) => o.ExternalDocs = LoadExternalDocs(n, t) + (o, n, t, c) => o.ExternalDocs = LoadExternalDocs(n, t, c) } }; @@ -31,7 +33,7 @@ internal static partial class OpenApiV3Deserializer { { s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), - (o, p, n, doc) => + (o, p, n, doc, c) => { if (p.Equals("x-oas-summary", StringComparison.OrdinalIgnoreCase)) { @@ -51,22 +53,19 @@ internal static partial class OpenApiV3Deserializer } else { - o.AddExtension(p, LoadExtension(p, n)); + o.AddExtension(p, LoadExtension(p, n, c)); } } } }; - public static OpenApiTag LoadTag(ParseNode n, OpenApiDocument hostDocument) + public static OpenApiTag LoadTag(JsonNode n, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = n.CheckMapNode("tag"); + var JsonObject = n.CheckMapNode("tag", context); var domainObject = new OpenApiTag(); - foreach (var propertyNode in mapNode) - { - propertyNode.ParseField(domainObject, _tagFixedFields, _tagPatternFields, hostDocument); - } + ParseMap(JsonObject, domainObject, _tagFixedFields, _tagPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs index 1a03268d6..ffed6ae7b 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Linq; @@ -13,33 +15,27 @@ namespace Microsoft.OpenApi.Reader.V3 internal static partial class OpenApiV3Deserializer { private static void ParseMap( - MapNode? mapNode, + JsonObject? jsonObject, T domainObject, FixedFieldMap fixedFieldMap, PatternFieldMap patternFieldMap, - OpenApiDocument hostDocument) + OpenApiDocument hostDocument, + ParsingContext context) { - if (mapNode == null) - { - return; - } - - foreach (var propertyNode in mapNode) - { - propertyNode.ParseField(domainObject, fixedFieldMap, patternFieldMap, hostDocument); - } + jsonObject.ParseMap(domainObject, fixedFieldMap, patternFieldMap, hostDocument, context); } private static void ProcessAnyFields( - MapNode mapNode, + JsonObject jsonObject, T domainObject, - AnyFieldMap anyFieldMap) + AnyFieldMap anyFieldMap, + ParsingContext context) { foreach (var anyFieldName in anyFieldMap.Keys.ToList()) { try { - mapNode.Context.StartObject(anyFieldName); + context.StartObject(anyFieldName); var any = anyFieldMap[anyFieldName].PropertyGetter(domainObject); @@ -54,32 +50,33 @@ private static void ProcessAnyFields( } catch (OpenApiException exception) { - exception.Pointer = mapNode.Context.GetLocation(); - mapNode.Context.Diagnostic.Errors.Add(new(exception)); + exception.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new(exception)); } finally { - mapNode.Context.EndObject(); + context.EndObject(); } } } private static void ProcessAnyMapFields( - MapNode mapNode, + JsonObject jsonObject, T domainObject, - AnyMapFieldMap anyMapFieldMap) + AnyMapFieldMap anyMapFieldMap, + ParsingContext context) { foreach (var anyMapFieldName in anyMapFieldMap.Keys.ToList()) { try { - mapNode.Context.StartObject(anyMapFieldName); + context.StartObject(anyMapFieldName); var mapElements = anyMapFieldMap[anyMapFieldName].PropertyMapGetter(domainObject); if (mapElements is not null) { foreach (var propertyMapElement in mapElements) { - mapNode.Context.StartObject(propertyMapElement.Key); + context.StartObject(propertyMapElement.Key); if (propertyMapElement.Value != null) { @@ -94,17 +91,17 @@ private static void ProcessAnyMapFields( } catch (OpenApiException exception) { - exception.Pointer = mapNode.Context.GetLocation(); - mapNode.Context.Diagnostic.Errors.Add(new(exception)); + exception.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new(exception)); } finally { - mapNode.Context.EndObject(); + context.EndObject(); } } } - private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(ParseNode node) + private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(JsonNode node) { var value = node.GetScalarValue(); @@ -123,14 +120,14 @@ private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(Parse }; } - public static JsonNodeExtension LoadAny(ParseNode node, OpenApiDocument hostDocument) + public static JsonNodeExtension LoadAny(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { return new JsonNodeExtension(node.CreateAny()); } - private static IOpenApiExtension LoadExtension(string name, ParseNode node) + private static IOpenApiExtension LoadExtension(string name, JsonNode node, ParsingContext context) { - if (node.Context.ExtensionParsers is not null && node.Context.ExtensionParsers.TryGetValue(name, out var parser)) + if (context.ExtensionParsers is not null && context.ExtensionParsers.TryGetValue(name, out var parser)) { try { @@ -142,15 +139,15 @@ private static IOpenApiExtension LoadExtension(string name, ParseNode node) } catch (OpenApiException ex) { - ex.Pointer = node.Context.GetLocation(); - node.Context.Diagnostic.Errors.Add(new(ex)); + ex.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new(ex)); } } return new JsonNodeExtension(node.CreateAny()); } - private static string? LoadString(ParseNode node) + private static string? LoadString(JsonNode node) { return node.GetScalarValue(); } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs index a5e24ff61..7d2709159 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Collections.Generic; @@ -20,7 +22,7 @@ public OpenApiV3VersionService(OpenApiDiagnostic diagnostic):base(diagnostic) { } - private readonly Dictionary> _loaders = new() + private readonly Dictionary> _loaders = new() { [typeof(JsonNodeExtension)] = OpenApiV3Deserializer.LoadAny, [typeof(OpenApiCallback)] = OpenApiV3Deserializer.LoadCallback, @@ -54,11 +56,11 @@ public OpenApiV3VersionService(OpenApiDiagnostic diagnostic):base(diagnostic) [typeof(OpenApiSchemaReference)] = OpenApiV3Deserializer.LoadMapping }; - internal override Dictionary> Loaders => _loaders; + internal override Dictionary> Loaders => _loaders; - public override OpenApiDocument LoadDocument(RootNode rootNode, Uri location) + public override OpenApiDocument LoadDocument(JsonNode JsonNode, Uri location, ParsingContext context) { - return OpenApiV3Deserializer.LoadOpenApi(rootNode, location); + return OpenApiV3Deserializer.LoadOpenApi(JsonNode, location, context); } } } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiXmlDeserializer.cs index 677cbfc0f..dc4451342 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiXmlDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V3 @@ -15,11 +17,11 @@ internal static partial class OpenApiV3Deserializer { { "name", - (o, n, _) => o.Name = n.GetScalarValue() + (o, n, _, c) => o.Name = n.GetScalarValue() }, { "namespace", - (o, n, _) => + (o, n, _, c) => { var value = n.GetScalarValue(); if (value != null) @@ -30,11 +32,11 @@ internal static partial class OpenApiV3Deserializer }, { "prefix", - (o, n, _) => o.Prefix = n.GetScalarValue() + (o, n, _, c) => o.Prefix = n.GetScalarValue() }, { "attribute", - (o, n, _) => + (o, n, _, c) => { var attribute = n.GetScalarValue(); if (attribute is not null) @@ -47,7 +49,7 @@ internal static partial class OpenApiV3Deserializer }, { "wrapped", - (o, n, _) => + (o, n, _, c) => { var wrapped = n.GetScalarValue(); if (wrapped is not null) @@ -63,18 +65,15 @@ internal static partial class OpenApiV3Deserializer private static readonly PatternFieldMap _xmlPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiXml LoadXml(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiXml LoadXml(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("xml"); + var JsonObject = node.CheckMapNode("xml", context); var xml = new OpenApiXml(); - foreach (var property in mapNode) - { - property.ParseField(xml, _xmlFixedFields, _xmlPatternFields, hostDocument); - } + ParseMap(JsonObject, xml, _xmlFixedFields, _xmlPatternFields, hostDocument, context); return xml; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiCallbackDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiCallbackDeserializer.cs index c7d72c847..f49ab8054 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiCallbackDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiCallbackDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -14,25 +15,25 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _callbackPatternFields = new() { - {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t) => o.AddPathItem(RuntimeExpression.Build(p), LoadPathItem(n, t))}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, + {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t, c) => o.AddPathItem(RuntimeExpression.Build(p), LoadPathItem(n, t, c))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))}, }; - public static IOpenApiCallback LoadCallback(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiCallback LoadCallback(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("callback"); + var JsonObject = node.CheckMapNode("callback", context); - if (mapNode.GetReferencePointer() is { } pointer) + if (JsonObject.GetReferencePointer() is { } pointer) { var reference = GetReferenceIdAndExternalResource(pointer); var callbackReference = new OpenApiCallbackReference(reference.Item1, hostDocument, reference.Item2); - callbackReference.Reference.SetMetadataFromMapNode(mapNode); + callbackReference.Reference.SetMetadataFromJsonObject(JsonObject); return callbackReference; } var domainObject = new OpenApiCallback(); - ParseMap(mapNode, domainObject, _callbackFixedFields, _callbackPatternFields, hostDocument); + ParseMap(JsonObject, domainObject, _callbackFixedFields, _callbackPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiComponentsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiComponentsDeserializer.cs index 24eadbcc9..532e13826 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiComponentsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiComponentsDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V31 @@ -13,30 +15,30 @@ internal static partial class OpenApiV31Deserializer { private static readonly FixedFieldMap _componentsFixedFields = new() { - {"schemas", (o, n, t) => o.Schemas = n.CreateMap(LoadSchema, t)}, - {"responses", (o, n, t) => o.Responses = n.CreateMap(LoadResponse, t)}, - {"parameters", (o, n, t) => o.Parameters = n.CreateMap(LoadParameter, t)}, - {"examples", (o, n, t) => o.Examples = n.CreateMap(LoadExample, t)}, - {"requestBodies", (o, n, t) => o.RequestBodies = n.CreateMap(LoadRequestBody, t)}, - {"headers", (o, n, t) => o.Headers = n.CreateMap(LoadHeader, t)}, - {"securitySchemes", (o, n, t) => o.SecuritySchemes = n.CreateMap(LoadSecurityScheme, t)}, - {"links", (o, n, t) => o.Links = n.CreateMap(LoadLink, t)}, - {"callbacks", (o, n, t) => o.Callbacks = n.CreateMap(LoadCallback, t)}, - {"pathItems", (o, n, t) => o.PathItems = n.CreateMap(LoadPathItem, t)} + {"schemas", (o, n, t, c) => o.Schemas = n.CreateMap(LoadSchema, t, c)}, + {"responses", (o, n, t, c) => o.Responses = n.CreateMap(LoadResponse, t, c)}, + {"parameters", (o, n, t, c) => o.Parameters = n.CreateMap(LoadParameter, t, c)}, + {"examples", (o, n, t, c) => o.Examples = n.CreateMap(LoadExample, t, c)}, + {"requestBodies", (o, n, t, c) => o.RequestBodies = n.CreateMap(LoadRequestBody, t, c)}, + {"headers", (o, n, t, c) => o.Headers = n.CreateMap(LoadHeader, t, c)}, + {"securitySchemes", (o, n, t, c) => o.SecuritySchemes = n.CreateMap(LoadSecurityScheme, t, c)}, + {"links", (o, n, t, c) => o.Links = n.CreateMap(LoadLink, t, c)}, + {"callbacks", (o, n, t, c) => o.Callbacks = n.CreateMap(LoadCallback, t, c)}, + {"pathItems", (o, n, t, c) => o.PathItems = n.CreateMap(LoadPathItem, t, c)} }; private static readonly PatternFieldMap _componentsPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiComponents LoadComponents(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiComponents LoadComponents(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("components"); + var JsonObject = node.CheckMapNode("components", context); var components = new OpenApiComponents(); - ParseMap(mapNode, components, _componentsFixedFields, _componentsPatternFields, hostDocument); + ParseMap(JsonObject, components, _componentsFixedFields, _componentsPatternFields, hostDocument, context); return components; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiContactDeserializer.cs index 0c1de16e1..f5787f699 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiContactDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -11,20 +12,20 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _contactFixedFields = new() { { - "name", (o, n, _) => + "name", (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { - "email", (o, n, _) => + "email", (o, n, _, c) => { o.Email = n.GetScalarValue(); } }, { "url", - (o, n, t) => + (o, n, t, c) => { var url = n.GetScalarValue(); if (url != null) @@ -37,15 +38,15 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _contactPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiContact LoadContact(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiContact LoadContact(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node as MapNode; + var JsonObject = node as JsonObject; var contact = new OpenApiContact(); - ParseMap(mapNode, contact, _contactFixedFields, _contactPatternFields, hostDocument); + ParseMap(JsonObject, contact, _contactFixedFields, _contactPatternFields, hostDocument, context); return contact; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiDiscriminatorDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiDiscriminatorDeserializer.cs index 3f4070827..f3553f620 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiDiscriminatorDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiDiscriminatorDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -12,15 +13,15 @@ internal static partial class OpenApiV31Deserializer new() { { - "propertyName", (o, n, _) => + "propertyName", (o, n, _, c) => { o.PropertyName = n.GetScalarValue(); } }, { - "mapping", (o, n, doc) => + "mapping", (o, n, doc, c) => { - o.Mapping = n.CreateSimpleMap((node) => LoadMapping(node, doc)); + o.Mapping = n.CreateSimpleMap(node => LoadMapping(node, doc, c), c); } } }; @@ -28,34 +29,31 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _discriminatorPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, doc) => { + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, doc, c) => { // Handle x-oas-default-mapping as DefaultMapping property if (p.Equals("x-oas-default-mapping", StringComparison.OrdinalIgnoreCase)) { - o.DefaultMapping = LoadMapping(n, doc); + o.DefaultMapping = LoadMapping(n, doc, c); } else { - o.AddExtension(p, LoadExtension(p, n)); + o.AddExtension(p, LoadExtension(p, n, c)); } } } }; - public static OpenApiDiscriminator LoadDiscriminator(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiDiscriminator LoadDiscriminator(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("discriminator"); + var JsonObject = node.CheckMapNode("discriminator", context); var discriminator = new OpenApiDiscriminator(); - foreach (var property in mapNode) - { - property.ParseField(discriminator, _discriminatorFixedFields, _discriminatorPatternFields, hostDocument); - } + ParseMap(JsonObject, discriminator, _discriminatorFixedFields, _discriminatorPatternFields, hostDocument, context); return discriminator; } - public static OpenApiSchemaReference LoadMapping(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiSchemaReference LoadMapping(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { var pointer = node.GetScalarValue() ?? throw new InvalidOperationException("Could not get a pointer reference"); var reference = GetReferenceIdAndExternalResource(pointer); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs index 4061edbc2..c30e1a0da 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; using System.Collections.Generic; namespace Microsoft.OpenApi.Reader.V31 @@ -12,25 +13,25 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _openApiFixedFields = new() { { - "openapi", (o, n, _) => + "openapi", (o, n, _, c) => { } /* Version is valid field but we already parsed it */ }, - {"info", (o, n, _) => o.Info = LoadInfo(n, o)}, - {"jsonSchemaDialect", (o, n, _) => { if (n.GetScalarValue() is string {} sjsd && Uri.TryCreate(sjsd, UriKind.Absolute, out var jsd)) {o.JsonSchemaDialect = jsd;}} }, - {"servers", (o, n, _) => o.Servers = n.CreateList(LoadServer, o)}, - {"paths", (o, n, _) => o.Paths = LoadPaths(n, o)}, - {"webhooks", (o, n, _) => o.Webhooks = n.CreateMap(LoadPathItem, o)}, - {"components", (o, n, _) => o.Components = LoadComponents(n, o)}, - {"tags", (o, n, _) => { if (n.CreateList(LoadTag, o) is {Count:> 0} tags) {o.Tags = new HashSet(tags, OpenApiTagComparer.Instance); } } }, - {"externalDocs", (o, n, _) => o.ExternalDocs = LoadExternalDocs(n, o)}, - {"security", (o, n, _) => o.Security = n.CreateList(LoadSecurityRequirement, o)} + {"info", (o, n, _, c) => o.Info = LoadInfo(n, o, c)}, + {"jsonSchemaDialect", (o, n, _, c) => { if (n.GetScalarValue() is string {} sjsd && Uri.TryCreate(sjsd, UriKind.Absolute, out var jsd)) {o.JsonSchemaDialect = jsd;}} }, + {"servers", (o, n, _, c) => o.Servers = n.CreateList(LoadServer, o, c)}, + {"paths", (o, n, _, c) => o.Paths = LoadPaths(n, o, c)}, + {"webhooks", (o, n, _, c) => o.Webhooks = n.CreateMap(LoadPathItem, o, c)}, + {"components", (o, n, _, c) => o.Components = LoadComponents(n, o, c)}, + {"tags", (o, n, _, c) => { if (n.CreateList(LoadTag, o, c) is {Count:> 0} tags) {o.Tags = new HashSet(tags, OpenApiTagComparer.Instance); } } }, + {"externalDocs", (o, n, _, c) => o.ExternalDocs = LoadExternalDocs(n, o, c)}, + {"security", (o, n, _, c) => o.Security = n.CreateList(LoadSecurityRequirement, o, c)} }; private static readonly PatternFieldMap _openApiPatternFields = new() { // We have no semantics to verify X- nodes, therefore treat them as just values. - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => { if (p.Equals("x-oai-$self", StringComparison.OrdinalIgnoreCase)) { @@ -42,20 +43,20 @@ internal static partial class OpenApiV31Deserializer } else { - o.AddExtension(p, LoadExtension(p, n)); + o.AddExtension(p, LoadExtension(p, n, c)); } }} }; - public static OpenApiDocument LoadOpenApi(RootNode rootNode, Uri location) + public static OpenApiDocument LoadOpenApi(JsonNode JsonNode, Uri location, ParsingContext context) { var openApiDoc = new OpenApiDocument { BaseUri = location }; - var openApiNode = rootNode.GetMap(); + var openApiNode = JsonNode.CheckMapNode("OpenAPI", context); - ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, openApiDoc); + ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, openApiDoc, context); // Register components openApiDoc.Workspace?.RegisterComponents(openApiDoc); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs index 3ed06d641..182516075 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31; /// @@ -10,21 +11,21 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _encodingFixedFields = new() { { - "contentType", (o, n, _) => + "contentType", (o, n, _, c) => { o.ContentType = n.GetScalarValue(); } }, { - "headers", (o, n, t) => + "headers", (o, n, t, c) => { - o.Headers = n.CreateMap(LoadHeader, t); + o.Headers = n.CreateMap(LoadHeader, t, c); } }, { - "style", (o, n, _) => + "style", (o, n, _, c) => { - if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + if(!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var style)) { return; } @@ -32,7 +33,7 @@ internal static partial class OpenApiV31Deserializer } }, { - "explode", (o, n, _) => + "explode", (o, n, _, c) => { var explode = n.GetScalarValue(); if (explode is not null) @@ -42,7 +43,7 @@ internal static partial class OpenApiV31Deserializer } }, { - "allowReserved", (o, n, _) => + "allowReserved", (o, n, _, c) => { var allowReserved = n.GetScalarValue(); if (allowReserved is not null) @@ -56,18 +57,15 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _encodingPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiEncoding LoadEncoding(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiEncoding LoadEncoding(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("encoding"); + var JsonObject = node.CheckMapNode("encoding", context); var encoding = new OpenApiEncoding(); - foreach (var property in mapNode) - { - property.ParseField(encoding, _encodingFixedFields, _encodingPatternFields, hostDocument); - } + ParseMap(JsonObject, encoding, _encodingFixedFields, _encodingPatternFields, hostDocument, context); return encoding; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiExampleDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiExampleDeserializer.cs index f9c0acbad..b6e522eb2 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiExampleDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiExampleDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -11,25 +12,25 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _exampleFixedFields = new() { { - "summary", (o, n, _) => + "summary", (o, n, _, c) => { o.Summary = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - "value", (o, n, _) => + "value", (o, n, _, c) => { o.Value = n.CreateAny(); } }, { - "externalValue", (o, n, _) => + "externalValue", (o, n, _, c) => { o.ExternalValue = n.GetScalarValue(); } @@ -40,29 +41,26 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _examplePatternFields = new() { - {s => s.Equals("x-oai-dataValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.DataValue = n.CreateAny()}, - {s => s.Equals("x-oai-serializedValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.SerializedValue = n.GetScalarValue()}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.Equals("x-oai-dataValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.DataValue = n.CreateAny()}, + {s => s.Equals("x-oai-serializedValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.SerializedValue = n.GetScalarValue()}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiExample LoadExample(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiExample LoadExample(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("example"); + var JsonObject = node.CheckMapNode("example", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var exampleReference = new OpenApiExampleReference(reference.Item1, hostDocument, reference.Item2); - exampleReference.Reference.SetMetadataFromMapNode(mapNode); + exampleReference.Reference.SetMetadataFromJsonObject(JsonObject); return exampleReference; } var example = new OpenApiExample(); - foreach (var property in mapNode) - { - property.ParseField(example, _exampleFixedFields, _examplePatternFields, hostDocument); - } + ParseMap(JsonObject, example, _exampleFixedFields, _examplePatternFields, hostDocument, context); return example; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiExternalDocsDeserializer.cs index 40b1b76de..2321ae2a5 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiExternalDocsDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -13,14 +14,14 @@ internal static partial class OpenApiV31Deserializer { // $ref { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { "url", - (o, n, t) => + (o, n, t, c) => { var url = n.GetScalarValue(); if (url != null) @@ -35,16 +36,16 @@ internal static partial class OpenApiV31Deserializer new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiExternalDocs LoadExternalDocs(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiExternalDocs LoadExternalDocs(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("externalDocs"); + var JsonObject = node.CheckMapNode("externalDocs", context); var externalDocs = new OpenApiExternalDocs(); - ParseMap(mapNode, externalDocs, _externalDocsFixedFields, _externalDocsPatternFields, hostDocument); + ParseMap(JsonObject, externalDocs, _externalDocsFixedFields, _externalDocsPatternFields, hostDocument, context); return externalDocs; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs index 208899b54..0901c82ff 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -11,14 +12,14 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _headerFixedFields = new() { { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { "required", - (o, n, _) => + (o, n, _, c) => { var required = n.GetScalarValue(); if (required != null) @@ -29,7 +30,7 @@ internal static partial class OpenApiV31Deserializer }, { "deprecated", - (o, n, _) => + (o, n, _, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -40,7 +41,7 @@ internal static partial class OpenApiV31Deserializer }, { "allowEmptyValue", - (o, n, _) => + (o, n, _, c) => { var allowEmptyVal = n.GetScalarValue(); if (allowEmptyVal != null) @@ -51,7 +52,7 @@ internal static partial class OpenApiV31Deserializer }, { "allowReserved", - (o, n, _) => + (o, n, _, c) => { var allowReserved = n.GetScalarValue(); if (allowReserved != null) @@ -61,9 +62,9 @@ internal static partial class OpenApiV31Deserializer } }, { - "style", (o, n, _) => + "style", (o, n, _, c) => { - if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + if(!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var style)) { return; } @@ -72,7 +73,7 @@ internal static partial class OpenApiV31Deserializer }, { "explode", - (o, n, _) => + (o, n, _, c) => { var explode = n.GetScalarValue(); if (explode != null) @@ -82,25 +83,25 @@ internal static partial class OpenApiV31Deserializer } }, { - "schema", (o, n, t) => + "schema", (o, n, t, c) => { - o.Schema = LoadSchema(n, t); + o.Schema = LoadSchema(n, t, c); } }, { - "content", (o, n, t) => + "content", (o, n, t, c) => { - o.Content = n.CreateMap(LoadMediaType, t); + o.Content = n.CreateMap(LoadMediaType, t, c); } }, { - "examples", (o, n, t) => + "examples", (o, n, t, c) => { - o.Examples = n.CreateMap(LoadExample, t); + o.Examples = n.CreateMap(LoadExample, t, c); } }, { - "example", (o, n, _) => + "example", (o, n, _, c) => { o.Example = n.CreateAny(); } @@ -109,27 +110,24 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _headerPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiHeader LoadHeader(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiHeader LoadHeader(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("header"); + var JsonObject = node.CheckMapNode("header", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var headerReference = new OpenApiHeaderReference(reference.Item1, hostDocument, reference.Item2); - headerReference.Reference.SetMetadataFromMapNode(mapNode); + headerReference.Reference.SetMetadataFromJsonObject(JsonObject); return headerReference; } var header = new OpenApiHeader(); - foreach (var property in mapNode) - { - property.ParseField(header, _headerFixedFields, _headerPatternFields, hostDocument); - } + ParseMap(JsonObject, header, _headerFixedFields, _headerPatternFields, hostDocument, context); return header; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiInfoDeserializer.cs index 99410cb0d..ef5c286e3 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiInfoDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -11,32 +12,32 @@ internal static partial class OpenApiV31Deserializer public static readonly FixedFieldMap InfoFixedFields = new() { { - "title", (o, n, _) => + "title", (o, n, _, c) => { o.Title = n.GetScalarValue(); } }, { - "version", (o, n, _) => + "version", (o, n, _, c) => { o.Version = n.GetScalarValue(); } }, { - "summary", (o, n, _) => + "summary", (o, n, _, c) => { o.Summary = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { "termsOfService", - (o, n, _) => + (o, n, _, c) => { var terms = n.GetScalarValue(); if (terms != null) @@ -46,29 +47,29 @@ internal static partial class OpenApiV31Deserializer } }, { - "contact", (o, n, t) => + "contact", (o, n, t, c) => { - o.Contact = LoadContact(n, t); + o.Contact = LoadContact(n, t, c); } }, { - "license", (o, n, t) => + "license", (o, n, t, c) => { - o.License = LoadLicense(n, t); + o.License = LoadLicense(n, t, c); } } }; public static readonly PatternFieldMap InfoPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, k, n, _) => o.AddExtension(k,LoadExtension(k, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, k, n, _, c) => o.AddExtension(k,LoadExtension(k, n, c))} }; - public static OpenApiInfo LoadInfo(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiInfo LoadInfo(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Info"); + var JsonObject = node.CheckMapNode("Info", context); var info = new OpenApiInfo(); - ParseMap(mapNode, info, InfoFixedFields, InfoPatternFields, hostDocument); + ParseMap(JsonObject, info, InfoFixedFields, InfoPatternFields, hostDocument, context); return info; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiLicenseDeserializer.cs index a1c37124b..c8eaa849a 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiLicenseDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -11,20 +12,20 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _licenseFixedFields = new() { { - "name", (o, n, _) => + "name", (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { - "identifier", (o, n, _) => + "identifier", (o, n, _, c) => { o.Identifier = n.GetScalarValue(); } }, { "url", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -37,16 +38,16 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _licensePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - internal static OpenApiLicense LoadLicense(ParseNode node, OpenApiDocument hostDocument) + internal static OpenApiLicense LoadLicense(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("License"); + var JsonObject = node.CheckMapNode("License", context); var license = new OpenApiLicense(); - ParseMap(mapNode, license, _licenseFixedFields, _licensePatternFields, hostDocument); + ParseMap(JsonObject, license, _licenseFixedFields, _licensePatternFields, hostDocument, context); return license; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiLinkDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiLinkDeserializer.cs index 435ee084b..db8bdac13 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiLinkDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiLinkDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -11,58 +12,58 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _linkFixedFields = new() { { - "operationRef", (o, n, _) => + "operationRef", (o, n, _, c) => { o.OperationRef = n.GetScalarValue(); } }, { - "operationId", (o, n, _) => + "operationId", (o, n, _, c) => { o.OperationId = n.GetScalarValue(); } }, { - "parameters", (o, n, _) => + "parameters", (o, n, _, c) => { - o.Parameters = n.CreateSimpleMap(LoadRuntimeExpressionAnyWrapper); + o.Parameters = n.CreateSimpleMap(LoadRuntimeExpressionAnyWrapper, c); } }, { - "requestBody", (o, n, _) => + "requestBody", (o, n, _, c) => { o.RequestBody = LoadRuntimeExpressionAnyWrapper(n); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, - {"server", (o, n, t) => o.Server = LoadServer(n, t)} + {"server", (o, n, t, c) => o.Server = LoadServer(n, t, c)} }; private static readonly PatternFieldMap _linkPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))}, }; - public static IOpenApiLink LoadLink(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiLink LoadLink(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("link"); + var JsonObject = node.CheckMapNode("link", context); var link = new OpenApiLink(); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var linkReference = new OpenApiLinkReference(reference.Item1, hostDocument, reference.Item2); - linkReference.Reference.SetMetadataFromMapNode(mapNode); + linkReference.Reference.SetMetadataFromJsonObject(JsonObject); return linkReference; } - ParseMap(mapNode, link, _linkFixedFields, _linkPatternFields, hostDocument); + ParseMap(JsonObject, link, _linkFixedFields, _linkPatternFields, hostDocument, context); return link; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiMediaTypeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiMediaTypeDeserializer.cs index 89c5e5f85..7243d7680 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiMediaTypeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiMediaTypeDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -12,39 +13,39 @@ internal static partial class OpenApiV31Deserializer new() { { - OpenApiConstants.Schema, (o, n, t) => + OpenApiConstants.Schema, (o, n, t, c) => { - o.Schema = LoadSchema(n, t); + o.Schema = LoadSchema(n, t, c); } }, { - OpenApiConstants.Examples, (o, n, t) => + OpenApiConstants.Examples, (o, n, t, c) => { - o.Examples = n.CreateMap(LoadExample, t); + o.Examples = n.CreateMap(LoadExample, t, c); } }, { - OpenApiConstants.Example, (o, n, _) => + OpenApiConstants.Example, (o, n, _, c) => { o.Example = n.CreateAny(); } }, { - OpenApiConstants.Encoding, (o, n, t) => + OpenApiConstants.Encoding, (o, n, t, c) => { - o.Encoding = n.CreateMap(LoadEncoding, t); + o.Encoding = n.CreateMap(LoadEncoding, t, c); } }, { - OpenApiConstants.ExtensionFieldNamePrefix + "oai-" + OpenApiConstants.ItemEncoding, (o, n, t) => + OpenApiConstants.ExtensionFieldNamePrefix + "oai-" + OpenApiConstants.ItemEncoding, (o, n, t, c) => { - o.ItemEncoding = LoadEncoding(n, t); + o.ItemEncoding = LoadEncoding(n, t, c); } }, { - OpenApiConstants.ExtensionFieldNamePrefix + "oai-" + OpenApiConstants.PrefixEncoding, (o, n, t) => + OpenApiConstants.ExtensionFieldNamePrefix + "oai-" + OpenApiConstants.PrefixEncoding, (o, n, t, c) => { - o.PrefixEncoding = n.CreateList(LoadEncoding, t); + o.PrefixEncoding = n.CreateList(LoadEncoding, t, c); } }, }; @@ -52,16 +53,16 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _mediaTypePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t) => + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t, c) => { // Handle x-oai-itemSchema as ItemSchema property for forward compatibility if (p.Equals("x-oai-itemSchema", StringComparison.OrdinalIgnoreCase)) { - o.ItemSchema = LoadSchema(n, t); + o.ItemSchema = LoadSchema(n, t, c); } else { - o.AddExtension(p, LoadExtension(p, n)); + o.AddExtension(p, LoadExtension(p, n, c)); } }} }; @@ -91,16 +92,16 @@ internal static partial class OpenApiV31Deserializer } }; - public static IOpenApiMediaType LoadMediaType(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiMediaType LoadMediaType(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode(OpenApiConstants.Content); + var JsonObject = node.CheckMapNode(OpenApiConstants.Content, context); var mediaType = new OpenApiMediaType(); - ParseMap(mapNode, mediaType, _mediaTypeFixedFields, _mediaTypePatternFields, hostDocument); + ParseMap(JsonObject, mediaType, _mediaTypeFixedFields, _mediaTypePatternFields, hostDocument, context); - ProcessAnyFields(mapNode, mediaType, _mediaTypeAnyFields); - ProcessAnyMapFields(mapNode, mediaType, _mediaTypeAnyMapOpenApiExampleFields); + ProcessAnyFields(JsonObject, mediaType, _mediaTypeAnyFields, context); + ProcessAnyMapFields(JsonObject, mediaType, _mediaTypeAnyMapOpenApiExampleFields, context); return mediaType; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowDeserializer.cs index c8c0ab23e..e1b89c16d 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; using System.Linq; namespace Microsoft.OpenApi.Reader.V31 @@ -14,7 +15,7 @@ internal static partial class OpenApiV31Deserializer { { "authorizationUrl", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -25,7 +26,7 @@ internal static partial class OpenApiV31Deserializer }, { "tokenUrl", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -36,7 +37,7 @@ internal static partial class OpenApiV31Deserializer }, { "refreshUrl", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -45,13 +46,13 @@ internal static partial class OpenApiV31Deserializer } } }, - {"scopes", (o, n, _) => o.Scopes = n.CreateSimpleMap(LoadString).Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value!)} + {"scopes", (o, n, _, c) => o.Scopes = n.CreateSimpleMap(LoadString, c).Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value!)} }; private static readonly PatternFieldMap _oAuthFlowPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => { if (p.Equals("x-oai-deviceAuthorizationUrl", StringComparison.OrdinalIgnoreCase)) { @@ -63,20 +64,17 @@ internal static partial class OpenApiV31Deserializer } else { - o.AddExtension(p, LoadExtension(p, n)); + o.AddExtension(p, LoadExtension(p, n, c)); } }} }; - public static OpenApiOAuthFlow LoadOAuthFlow(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiOAuthFlow LoadOAuthFlow(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("OAuthFlow"); + var JsonObject = node.CheckMapNode("OAuthFlow", context); var oauthFlow = new OpenApiOAuthFlow(); - foreach (var property in mapNode) - { - property.ParseField(oauthFlow, _oAuthFlowFixedFileds, _oAuthFlowPatternFields, hostDocument); - } + ParseMap(JsonObject, oauthFlow, _oAuthFlowFixedFileds, _oAuthFlowPatternFields, hostDocument, context); return oauthFlow; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowsDeserializer.cs index fd37a4032..a0dc0a0e3 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowsDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -11,28 +12,25 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _oAuthFlowsFixedFields = new() { - {"implicit", (o, n, t) => o.Implicit = LoadOAuthFlow(n, t)}, - {"password", (o, n, t) => o.Password = LoadOAuthFlow(n, t)}, - {"clientCredentials", (o, n, t) => o.ClientCredentials = LoadOAuthFlow(n, t)}, - {"authorizationCode", (o, n, t) => o.AuthorizationCode = LoadOAuthFlow(n, t)} + {"implicit", (o, n, t, c) => o.Implicit = LoadOAuthFlow(n, t, c)}, + {"password", (o, n, t, c) => o.Password = LoadOAuthFlow(n, t, c)}, + {"clientCredentials", (o, n, t, c) => o.ClientCredentials = LoadOAuthFlow(n, t, c)}, + {"authorizationCode", (o, n, t, c) => o.AuthorizationCode = LoadOAuthFlow(n, t, c)} }; private static readonly PatternFieldMap _oAuthFlowsPatternFields = new() { - {s => s.Equals("x-oai-deviceAuthorization", StringComparison.OrdinalIgnoreCase), (o, p, n, t) => o.DeviceAuthorization = LoadOAuthFlow(n, t)}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.Equals("x-oai-deviceAuthorization", StringComparison.OrdinalIgnoreCase), (o, p, n, t, c) => o.DeviceAuthorization = LoadOAuthFlow(n, t, c)}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiOAuthFlows LoadOAuthFlows(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiOAuthFlows LoadOAuthFlows(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("OAuthFlows"); + var JsonObject = node.CheckMapNode("OAuthFlows", context); var oAuthFlows = new OpenApiOAuthFlows(); - foreach (var property in mapNode) - { - property.ParseField(oAuthFlows, _oAuthFlowsFixedFields, _oAuthFlowsPatternFields, hostDocument); - } + ParseMap(JsonObject, oAuthFlows, _oAuthFlowsFixedFields, _oAuthFlowsPatternFields, hostDocument, context); return oAuthFlows; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiOperationDeserializer.cs index 101b844c0..3f8776a5a 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiOperationDeserializer.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text.Json.Nodes; @@ -15,16 +15,17 @@ internal static partial class OpenApiV31Deserializer new() { { - "tags", (o, n, doc) => { + "tags", (o, n, doc, c) => { if (n.CreateSimpleList( - (valueNode, doc) => + (jsonNode, document) => { - var val = valueNode.GetScalarValue(); + var val = jsonNode.GetScalarValue(); if (string.IsNullOrEmpty(val)) return null; // Avoid exception on empty tag, we'll remove these from the list further on - return LoadTagByReference(val , doc); - }, - doc) + return LoadTagByReference(val!, document); + }, + doc, + c) // Filter out empty tags instead of excepting on them .OfType().ToList() is {Count: > 0} tags) { @@ -33,56 +34,56 @@ internal static partial class OpenApiV31Deserializer } }, { - "summary", (o, n, _) => + "summary", (o, n, _, c) => { o.Summary = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - "externalDocs", (o, n, t) => + "externalDocs", (o, n, t, c) => { - o.ExternalDocs = LoadExternalDocs(n, t); + o.ExternalDocs = LoadExternalDocs(n, t, c); } }, { - "operationId", (o, n, _) => + "operationId", (o, n, _, c) => { o.OperationId = n.GetScalarValue(); } }, { - "parameters", (o, n, t) => + "parameters", (o, n, t, c) => { - o.Parameters = n.CreateList(LoadParameter, t); + o.Parameters = n.CreateList(LoadParameter, t, c); } }, { - "requestBody", (o, n, t) => + "requestBody", (o, n, t, c) => { - o.RequestBody = LoadRequestBody(n, t); + o.RequestBody = LoadRequestBody(n, t, c); } }, { - "responses", (o, n, t) => + "responses", (o, n, t, c) => { - o.Responses = LoadResponses(n, t); + o.Responses = LoadResponses(n, t, c); } }, { - "callbacks", (o, n, t) => + "callbacks", (o, n, t, c) => { - o.Callbacks = n.CreateMap(LoadCallback, t); + o.Callbacks = n.CreateMap(LoadCallback, t, c); } }, { "deprecated", - (o, n, _) => + (o, n, _, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -92,18 +93,18 @@ internal static partial class OpenApiV31Deserializer } }, { - "security", (o, n, t) => + "security", (o, n, t, c) => { - if (n.JsonNode is JsonArray) + if (n is JsonArray) { - o.Security = n.CreateList(LoadSecurityRequirement, t); + o.Security = n.CreateList(LoadSecurityRequirement, t, c); } } }, { - "servers", (o, n, t) => + "servers", (o, n, t, c) => { - o.Servers = n.CreateList(LoadServer, t); + o.Servers = n.CreateList(LoadServer, t, c); } }, }; @@ -111,16 +112,16 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _operationPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))}, }; - internal static OpenApiOperation LoadOperation(ParseNode node, OpenApiDocument hostDocument) + internal static OpenApiOperation LoadOperation(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Operation"); + var JsonObject = node.CheckMapNode("Operation", context); var operation = new OpenApiOperation(); - ParseMap(mapNode, operation, _operationFixedFields, _operationPatternFields, hostDocument); + ParseMap(JsonObject, operation, _operationFixedFields, _operationPatternFields, hostDocument, context); return operation; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs index 0b6686ca1..648fdec3a 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -12,15 +13,15 @@ internal static partial class OpenApiV31Deserializer new() { { - "name", (o, n, _) => + "name", (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { - "in", (o, n, _) => + "in", (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var _in)) { return; } @@ -28,14 +29,14 @@ internal static partial class OpenApiV31Deserializer } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { "required", - (o, n, t) => + (o, n, t, c) => { var required = n.GetScalarValue(); if (required != null) @@ -46,7 +47,7 @@ internal static partial class OpenApiV31Deserializer }, { "deprecated", - (o, n, t) => + (o, n, t, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -57,7 +58,7 @@ internal static partial class OpenApiV31Deserializer }, { "allowEmptyValue", - (o, n, t) => + (o, n, t, c) => { var allowEmptyValue = n.GetScalarValue(); if (allowEmptyValue != null) @@ -68,7 +69,7 @@ internal static partial class OpenApiV31Deserializer }, { "allowReserved", - (o, n, _) => + (o, n, _, c) => { var allowReserved = n.GetScalarValue(); if (allowReserved != null) @@ -78,9 +79,9 @@ internal static partial class OpenApiV31Deserializer } }, { - "style", (o, n, _) => + "style", (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var style)) { return; } @@ -88,7 +89,7 @@ internal static partial class OpenApiV31Deserializer } }, { - "explode", (o, n, _) => + "explode", (o, n, _, c) => { var explode = n.GetScalarValue(); if (explode != null) @@ -98,25 +99,25 @@ internal static partial class OpenApiV31Deserializer } }, { - "schema", (o, n, t) => + "schema", (o, n, t, c) => { - o.Schema = LoadSchema(n, t); + o.Schema = LoadSchema(n, t, c); } }, { - "content", (o, n, t) => + "content", (o, n, t, c) => { - o.Content = n.CreateMap(LoadMediaType, t); + o.Content = n.CreateMap(LoadMediaType, t, c); } }, { - "examples", (o, n, t) => + "examples", (o, n, t, c) => { - o.Examples = n.CreateMap(LoadExample, t); + o.Examples = n.CreateMap(LoadExample, t, c); } }, { - "example", (o, n, _) => + "example", (o, n, _, c) => { o.Example = n.CreateAny(); } @@ -126,7 +127,7 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _parameterPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; private static readonly AnyFieldMap _parameterAnyFields = new AnyFieldMap @@ -153,24 +154,24 @@ internal static partial class OpenApiV31Deserializer } }; - public static IOpenApiParameter LoadParameter(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiParameter LoadParameter(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("parameter"); + var JsonObject = node.CheckMapNode("parameter", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var parameterReference = new OpenApiParameterReference(reference.Item1, hostDocument, reference.Item2); - parameterReference.Reference.SetMetadataFromMapNode(mapNode); + parameterReference.Reference.SetMetadataFromJsonObject(JsonObject); return parameterReference; } var parameter = new OpenApiParameter(); - ParseMap(mapNode, parameter, _parameterFixedFields, _parameterPatternFields, hostDocument); - ProcessAnyFields(mapNode, parameter, _parameterAnyFields); - ProcessAnyMapFields(mapNode, parameter, _parameterAnyMapOpenApiExampleFields); + ParseMap(JsonObject, parameter, _parameterFixedFields, _parameterPatternFields, hostDocument, context); + ProcessAnyFields(JsonObject, parameter, _parameterAnyFields, context); + ProcessAnyMapFields(JsonObject, parameter, _parameterAnyMapOpenApiExampleFields, context); return parameter; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiPathItemDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiPathItemDeserializer.cs index 892c1e8a1..a65c797c1 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiPathItemDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiPathItemDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; using System.Net.Http; namespace Microsoft.OpenApi.Reader.V31 @@ -13,56 +14,56 @@ internal static partial class OpenApiV31Deserializer { { - "summary", (o, n, _) => + "summary", (o, n, _, c) => { o.Summary = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, - {"get", (o, n, t) => o.AddOperation(HttpMethod.Get, LoadOperation(n, t))}, - {"put", (o, n, t) => o.AddOperation(HttpMethod.Put, LoadOperation(n, t))}, - {"post", (o, n, t) => o.AddOperation(HttpMethod.Post, LoadOperation(n, t))}, - {"delete", (o, n, t) => o.AddOperation(HttpMethod.Delete, LoadOperation(n, t))}, - {"options", (o, n, t) => o.AddOperation(HttpMethod.Options, LoadOperation(n, t))}, - {"head", (o, n, t) => o.AddOperation(HttpMethod.Head, LoadOperation(n, t))}, + {"get", (o, n, t, c) => o.AddOperation(HttpMethod.Get, LoadOperation(n, t, c))}, + {"put", (o, n, t, c) => o.AddOperation(HttpMethod.Put, LoadOperation(n, t, c))}, + {"post", (o, n, t, c) => o.AddOperation(HttpMethod.Post, LoadOperation(n, t, c))}, + {"delete", (o, n, t, c) => o.AddOperation(HttpMethod.Delete, LoadOperation(n, t, c))}, + {"options", (o, n, t, c) => o.AddOperation(HttpMethod.Options, LoadOperation(n, t, c))}, + {"head", (o, n, t, c) => o.AddOperation(HttpMethod.Head, LoadOperation(n, t, c))}, #if NETSTANDARD2_1_OR_GREATER - {"patch", (o, n, t) => o.AddOperation(HttpMethod.Patch, LoadOperation(n, t))}, + {"patch", (o, n, t, c) => o.AddOperation(HttpMethod.Patch, LoadOperation(n, t, c))}, #else - {"patch", (o, n, t) => o.AddOperation(new HttpMethod("PATCH"), LoadOperation(n, t))}, + {"patch", (o, n, t, c) => o.AddOperation(new HttpMethod("PATCH"), LoadOperation(n, t, c))}, #endif - {"trace", (o, n, t) => o.AddOperation(HttpMethod.Trace, LoadOperation(n, t))}, - {"servers", (o, n, t) => o.Servers = n.CreateList(LoadServer, t)}, - {"parameters", (o, n, t) => o.Parameters = n.CreateList(LoadParameter, t)} + {"trace", (o, n, t, c) => o.AddOperation(HttpMethod.Trace, LoadOperation(n, t, c))}, + {"servers", (o, n, t, c) => o.Servers = n.CreateList(LoadServer, t, c)}, + {"parameters", (o, n, t, c) => o.Parameters = n.CreateList(LoadParameter, t, c)} }; private static readonly PatternFieldMap _pathItemPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiPathItem LoadPathItem(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiPathItem LoadPathItem(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("PathItem"); + var JsonObject = node.CheckMapNode("PathItem", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var pathItemReference = new OpenApiPathItemReference(reference.Item1, hostDocument, reference.Item2); - pathItemReference.Reference.SetMetadataFromMapNode(mapNode); + pathItemReference.Reference.SetMetadataFromJsonObject(JsonObject); return pathItemReference; } var pathItem = new OpenApiPathItem(); - ParseMap(mapNode, pathItem, _pathItemFixedFields, _pathItemPatternFields, hostDocument); + ParseMap(JsonObject, pathItem, _pathItemFixedFields, _pathItemPatternFields, hostDocument, context); return pathItem; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiPathsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiPathsDeserializer.cs index 499864cb5..867e0f255 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiPathsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiPathsDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -12,17 +13,17 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _pathsPatternFields = new() { - {s => s.StartsWith("/", StringComparison.OrdinalIgnoreCase), (o, k, n, t) => o.Add(k, LoadPathItem(n, t))}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith("/", StringComparison.OrdinalIgnoreCase), (o, k, n, t, c) => o.Add(k, LoadPathItem(n, t, c))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiPaths LoadPaths(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiPaths LoadPaths(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Paths"); + var JsonObject = node.CheckMapNode("Paths", context); var domainObject = new OpenApiPaths(); - ParseMap(mapNode, domainObject, _pathsFixedFields, _pathsPatternFields, hostDocument); + ParseMap(JsonObject, domainObject, _pathsFixedFields, _pathsPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiRequestBodyDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiRequestBodyDeserializer.cs index de40027db..9a8c424af 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiRequestBodyDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiRequestBodyDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -12,19 +13,19 @@ internal static partial class OpenApiV31Deserializer new() { { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - "content", (o, n, t) => + "content", (o, n, t, c) => { - o.Content = n.CreateMap(LoadMediaType, t); + o.Content = n.CreateMap(LoadMediaType, t, c); } }, { - "required", (o, n, _) => + "required", (o, n, _, c) => { var required = n.GetScalarValue(); if (required != null) @@ -38,27 +39,24 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _requestBodyPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiRequestBody LoadRequestBody(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiRequestBody LoadRequestBody(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("requestBody"); + var JsonObject = node.CheckMapNode("requestBody", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var requestBodyReference = new OpenApiRequestBodyReference(reference.Item1, hostDocument, reference.Item2); - requestBodyReference.Reference.SetMetadataFromMapNode(mapNode); + requestBodyReference.Reference.SetMetadataFromJsonObject(JsonObject); return requestBodyReference; } var requestBody = new OpenApiRequestBody(); - foreach (var property in mapNode) - { - property.ParseField(requestBody, _requestBodyFixedFields, _requestBodyPatternFields, hostDocument); - } + ParseMap(JsonObject, requestBody, _requestBodyFixedFields, _requestBodyPatternFields, hostDocument, context); return requestBody; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiResponseDeserializer.cs index d00b3eb80..8680a50f5 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiResponseDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V31 { @@ -11,27 +12,27 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _responseFixedFields = new() { { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - "headers", (o, n, t) => + "headers", (o, n, t, c) => { - o.Headers = n.CreateMap(LoadHeader, t); + o.Headers = n.CreateMap(LoadHeader, t, c); } }, { - "content", (o, n, t) => + "content", (o, n, t, c) => { - o.Content = n.CreateMap(LoadMediaType, t); + o.Content = n.CreateMap(LoadMediaType, t, c); } }, { - "links", (o, n, t) => + "links", (o, n, t, c) => { - o.Links = n.CreateMap(LoadLink, t); + o.Links = n.CreateMap(LoadLink, t, c); } } }; @@ -39,7 +40,7 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _responsePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => { if (p.Equals("x-oai-summary", StringComparison.OrdinalIgnoreCase)) { @@ -47,26 +48,26 @@ internal static partial class OpenApiV31Deserializer } else { - o.AddExtension(p, LoadExtension(p,n)); + o.AddExtension(p, LoadExtension(p, n, c)); } }} }; - public static IOpenApiResponse LoadResponse(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiResponse LoadResponse(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("response"); + var JsonObject = node.CheckMapNode("response", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var responseReference = new OpenApiResponseReference(reference.Item1, hostDocument, reference.Item2); - responseReference.Reference.SetMetadataFromMapNode(mapNode); + responseReference.Reference.SetMetadataFromJsonObject(JsonObject); return responseReference; } var response = new OpenApiResponse(); - ParseMap(mapNode, response, _responseFixedFields, _responsePatternFields, hostDocument); + ParseMap(JsonObject, response, _responseFixedFields, _responsePatternFields, hostDocument, context); return response; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiResponsesDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiResponsesDeserializer.cs index 281427bef..b33ca4e0a 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiResponsesDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiResponsesDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V31 @@ -15,17 +17,17 @@ internal static partial class OpenApiV31Deserializer public static readonly PatternFieldMap ResponsesPatternFields = new() { - {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t) => o.Add(p, LoadResponse(n, t))}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t, c) => o.Add(p, LoadResponse(n, t, c))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiResponses LoadResponses(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiResponses LoadResponses(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Responses"); + var JsonObject = node.CheckMapNode("Responses", context); var domainObject = new OpenApiResponses(); - ParseMap(mapNode, domainObject, ResponsesFixedFields, ResponsesPatternFields, hostDocument); + ParseMap(JsonObject, domainObject, ResponsesFixedFields, ResponsesPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs index 39c32c979..2e3c3d2a2 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; @@ -14,39 +14,39 @@ internal static partial class OpenApiV31Deserializer { { "title", - (o, n, _) => o.Title = n.GetScalarValue() + (o, n, _, c) => o.Title = n.GetScalarValue() }, { "$schema", - (o, n, _) => { if (n.GetScalarValue() is string {} sSchema && Uri.TryCreate(sSchema, UriKind.Absolute, out var schema)) {o.Schema = schema;}} + (o, n, _, c) => { if (n.GetScalarValue() is string {} sSchema && Uri.TryCreate(sSchema, UriKind.Absolute, out var schema)) {o.Schema = schema;}} }, { "$id", - (o, n, _) => o.Id = n.GetScalarValue() + (o, n, _, c) => o.Id = n.GetScalarValue() }, { "$comment", - (o, n, _) => o.Comment = n.GetScalarValue() + (o, n, _, c) => o.Comment = n.GetScalarValue() }, { "$vocabulary", - (o, n, _) => o.Vocabulary = n.CreateSimpleMap(LoadBool).ToDictionary(kvp => kvp.Key, kvp => kvp.Value ?? false) + (o, n, _, c) => o.Vocabulary = n.CreateSimpleMap(LoadBool, c).ToDictionary(kvp => kvp.Key, kvp => kvp.Value ?? false) }, { "$dynamicRef", - (o, n, _) => o.DynamicRef = n.GetScalarValue() + (o, n, _, c) => o.DynamicRef = n.GetScalarValue() }, { "$dynamicAnchor", - (o, n, _) => o.DynamicAnchor = n.GetScalarValue() + (o, n, _, c) => o.DynamicAnchor = n.GetScalarValue() }, { "$defs", - (o, n, t) => o.Definitions = n.CreateMap(LoadSchema, t) + (o, n, t, c) => o.Definitions = n.CreateMap(LoadSchema, t, c) }, { "multipleOf", - (o, n, _) => + (o, n, _, c) => { var multipleOf = n.GetScalarValue(); if (multipleOf != null) @@ -57,7 +57,7 @@ internal static partial class OpenApiV31Deserializer }, { "maximum", - (o, n,_) => + (o, n, _, c) => { var max = n.GetScalarValue(); if (!string.IsNullOrEmpty(max)) @@ -68,11 +68,11 @@ internal static partial class OpenApiV31Deserializer }, { "exclusiveMaximum", - (o, n, _) => o.ExclusiveMaximum = n.GetScalarValue() + (o, n, _, c) => o.ExclusiveMaximum = n.GetScalarValue() }, { "minimum", - (o, n, _) => + (o, n, _, c) => { var min = n.GetScalarValue(); if (!string.IsNullOrEmpty(min)) @@ -83,11 +83,11 @@ internal static partial class OpenApiV31Deserializer }, { "exclusiveMinimum", - (o, n, _) => o.ExclusiveMinimum = n.GetScalarValue() + (o, n, _, c) => o.ExclusiveMinimum = n.GetScalarValue() }, { "maxLength", - (o, n, _) => + (o, n, _, c) => { var maxLength = n.GetScalarValue(); if (maxLength != null) @@ -98,7 +98,7 @@ internal static partial class OpenApiV31Deserializer }, { "minLength", - (o, n, _) => + (o, n, _, c) => { var minLength = n.GetScalarValue(); if (minLength != null) @@ -109,11 +109,11 @@ internal static partial class OpenApiV31Deserializer }, { "pattern", - (o, n, _) => o.Pattern = n.GetScalarValue() + (o, n, _, c) => o.Pattern = n.GetScalarValue() }, { "maxItems", - (o, n, _) => + (o, n, _, c) => { var maxItems = n.GetScalarValue(); if (maxItems != null) @@ -124,7 +124,7 @@ internal static partial class OpenApiV31Deserializer }, { "minItems", - (o, n, _) => + (o, n, _, c) => { var minItems = n.GetScalarValue(); if (minItems != null) @@ -135,7 +135,7 @@ internal static partial class OpenApiV31Deserializer }, { "uniqueItems", - (o, n, _) => + (o, n, _, c) => { var uniqueItems = n.GetScalarValue(); if (uniqueItems != null) @@ -146,10 +146,10 @@ internal static partial class OpenApiV31Deserializer }, { "unevaluatedProperties", - (o, n, t) => + (o, n, t, c) => { // Handle both boolean (false/true) and schema object cases - if (n is ValueNode) + if (n is JsonValue) { var value = n.GetScalarValue(); if (value is not null) @@ -160,13 +160,13 @@ internal static partial class OpenApiV31Deserializer else { // Schema object case: deserialize as schema - o.UnevaluatedPropertiesSchema = LoadSchema(n, t); + o.UnevaluatedPropertiesSchema = LoadSchema(n, t, c); } } }, { "maxProperties", - (o, n, _) => + (o, n, _, c) => { var maxProps = n.GetScalarValue(); if (maxProps != null) @@ -177,7 +177,7 @@ internal static partial class OpenApiV31Deserializer }, { "minProperties", - (o, n, _) => + (o, n, _, c) => { var minProps = n.GetScalarValue(); if (minProps != null) @@ -188,23 +188,23 @@ internal static partial class OpenApiV31Deserializer }, { "required", - (o, n, doc) => o.Required = new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc).Where(s => s != null)) + (o, n, doc, c) => o.Required = new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc, c).OfType()) }, { "enum", - (o, n, _) => o.Enum = n.CreateListOfAny() + (o, n, _, c) => o.Enum = n.CreateListOfAny(c) }, { "type", - (o, n, doc) => + (o, n, doc, c) => { - if (n is ValueNode) + if (n is JsonValue) { o.Type = n.GetScalarValue()?.ToJsonSchemaType(); } else { - var list = n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc); + var list = n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc, c); JsonSchemaType combinedType = 0; foreach(var type in list.Where(static t => t is not null).Select(static t => t!.ToJsonSchemaType())) { @@ -216,40 +216,40 @@ internal static partial class OpenApiV31Deserializer }, { "const", - (o, n, _) => o.Const = n.GetScalarValue() + (o, n, _, c) => o.Const = n.GetScalarValue() }, { "allOf", - (o, n, t) => o.AllOf = n.CreateList(LoadSchema, t) + (o, n, t, c) => o.AllOf = n.CreateList(LoadSchema, t, c) }, { "oneOf", - (o, n, t) => o.OneOf = n.CreateList(LoadSchema, t) + (o, n, t, c) => o.OneOf = n.CreateList(LoadSchema, t, c) }, { "anyOf", - (o, n, t) => o.AnyOf = n.CreateList(LoadSchema, t) + (o, n, t, c) => o.AnyOf = n.CreateList(LoadSchema, t, c) }, { "not", - (o, n, doc) => o.Not = LoadSchema(n, doc) + (o, n, doc, c) => o.Not = LoadSchema(n, doc, c) }, { "items", - (o, n, doc) => o.Items = LoadSchema(n, doc) + (o, n, doc, c) => o.Items = LoadSchema(n, doc, c) }, { "properties", - (o, n, t) => o.Properties = n.CreateMap(LoadSchema, t) + (o, n, t, c) => o.Properties = n.CreateMap(LoadSchema, t, c) }, { "patternProperties", - (o, n, t) => o.PatternProperties = n.CreateMap(LoadSchema, t) + (o, n, t, c) => o.PatternProperties = n.CreateMap(LoadSchema, t, c) }, { - "additionalProperties", (o, n, doc) => + "additionalProperties", (o, n, doc, c) => { - if (n is ValueNode) + if (n is JsonValue) { var value = n.GetScalarValue(); if (value is not null) @@ -259,25 +259,25 @@ internal static partial class OpenApiV31Deserializer } else { - o.AdditionalProperties = LoadSchema(n, doc); + o.AdditionalProperties = LoadSchema(n, doc, c); } } }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "format", - (o, n, _) => o.Format = n.GetScalarValue() + (o, n, _, c) => o.Format = n.GetScalarValue() }, { "default", - (o, n, _) => o.Default = n.CreateAny() + (o, n, _, c) => o.Default = n.CreateAny() }, { "nullable", - (o, n, _) => + (o, n, _, c) => { var value = n.GetScalarValue(); if (value is not null) @@ -295,11 +295,11 @@ internal static partial class OpenApiV31Deserializer }, { "discriminator", - (o, n, doc) => o.Discriminator = LoadDiscriminator(n, doc) + (o, n, doc, c) => o.Discriminator = LoadDiscriminator(n, doc, c) }, { "readOnly", - (o, n, _) => + (o, n, _, c) => { var readOnly = n.GetScalarValue(); if (readOnly != null) @@ -310,7 +310,7 @@ internal static partial class OpenApiV31Deserializer }, { "writeOnly", - (o, n, _) => + (o, n, _, c) => { var writeOnly = n.GetScalarValue(); if (writeOnly != null) @@ -321,23 +321,23 @@ internal static partial class OpenApiV31Deserializer }, { "xml", - (o, n, doc) => o.Xml = LoadXml(n, doc) + (o, n, doc, c) => o.Xml = LoadXml(n, doc, c) }, { "externalDocs", - (o, n, doc) => o.ExternalDocs = LoadExternalDocs(n, doc) + (o, n, doc, c) => o.ExternalDocs = LoadExternalDocs(n, doc, c) }, { "example", - (o, n, _) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n.CreateAny() }, { "examples", - (o, n, _) => o.Examples = n.CreateListOfAny() + (o, n, _, c) => o.Examples = n.CreateListOfAny(c) }, { "deprecated", - (o, n, t) => + (o, n, t, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -348,22 +348,22 @@ internal static partial class OpenApiV31Deserializer }, { "dependentRequired", - (o, n, doc) => + (o, n, doc, c) => { - o.DependentRequired = n.CreateArrayMap((n2, p) => n2.GetScalarValue(), doc); + o.DependentRequired = n.CreateArrayMap((n2, p) => n2.GetScalarValue()!, doc, c); } }, }; private static readonly PatternFieldMap _openApiSchemaPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiSchema LoadSchema(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiSchema LoadSchema(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { // Handle boolean schemas (true/false) for JSON Schema 2020-12 compatibility - if (node is ValueNode valueNode && valueNode.TryGetValue(out var boolValue)) + if (node is JsonValue jsonValue && jsonValue.TryGetValue(out var boolValue)) { var boolSchema = new OpenApiSchema(); if (!boolValue) @@ -375,38 +375,29 @@ public static IOpenApiSchema LoadSchema(ParseNode node, OpenApiDocument hostDocu return boolSchema; } - var mapNode = node.CheckMapNode(OpenApiConstants.Schema); + var JsonObject = node.CheckMapNode(OpenApiConstants.Schema, context); - var pointer = mapNode.GetReferencePointer(); - var identifier = mapNode.GetJsonSchemaIdentifier(); + var pointer = JsonObject.GetReferencePointer(); + var identifier = JsonObject.GetJsonSchemaIdentifier(); if (pointer != null) { - var nodeLocation = node.Context.GetLocation(); + var nodeLocation = context.GetLocation(); var reference = GetReferenceIdAndExternalResource(pointer); var result = new OpenApiSchemaReference(reference.Item1, hostDocument, reference.Item2); - result.Reference.SetMetadataFromMapNode(mapNode); + result.Reference.SetMetadataFromJsonObject(JsonObject); result.Reference.SetJsonPointerPath(pointer, nodeLocation); return result; } var schema = new OpenApiSchema(); - foreach (var propertyNode in mapNode) - { - bool isRecognized = _openApiSchemaFixedFields.ContainsKey(propertyNode.Name) || - _openApiSchemaPatternFields.Any(p => p.Key(propertyNode.Name)); - - if (isRecognized) - { - propertyNode.ParseField(schema, _openApiSchemaFixedFields, _openApiSchemaPatternFields, hostDocument); - } - else if (propertyNode.JsonNode is not null) + JsonObject.ParseMap(schema, _openApiSchemaFixedFields, _openApiSchemaPatternFields, hostDocument, context, + static (schema, name, value) => { schema.UnrecognizedKeywords ??= new Dictionary(StringComparer.Ordinal); - schema.UnrecognizedKeywords[propertyNode.Name] = propertyNode.JsonNode; - } - } + schema.UnrecognizedKeywords[name] = value; + }); if (schema.Extensions is not null && schema.Extensions.ContainsKey(OpenApiConstants.NullableExtension)) { diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecurityRequirementDeserializer.cs index 0d7d71c70..ccf6cc076 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecurityRequirementDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System.Linq; namespace Microsoft.OpenApi.Reader.V31 @@ -11,17 +13,17 @@ namespace Microsoft.OpenApi.Reader.V31 /// internal static partial class OpenApiV31Deserializer { - public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiSecurityRequirement LoadSecurityRequirement(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("security"); + var JsonObject = node.CheckMapNode("security", context); var securityRequirement = new OpenApiSecurityRequirement(); - foreach (var property in mapNode) + foreach (var property in JsonObject) { - var scheme = LoadSecuritySchemeByReference(property.Name, hostDocument); + var scheme = LoadSecuritySchemeByReference(property.Key, hostDocument); - var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue(), hostDocument) + var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue(), hostDocument, context) .OfType() .ToList(); if (scheme != null) @@ -30,8 +32,8 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, } else { - mapNode.Context.Diagnostic.Errors.Add( - new OpenApiError(node.Context.GetLocation(), $"Scheme {property.Name} is not found")); + context.Diagnostic.Errors.Add( + new OpenApiError(context.GetLocation(), $"Scheme {property.Key} is not found")); } } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs index c315b229a..3fd297ebf 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V31 @@ -15,9 +17,9 @@ internal static partial class OpenApiV31Deserializer new() { { - "type", (o, n, _) => + "type", (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var type)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var type)) { return; } @@ -25,21 +27,21 @@ internal static partial class OpenApiV31Deserializer } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - "name", (o, n, _) => + "name", (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { - "in", (o, n, _) => + "in", (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var _in)) { return; } @@ -47,19 +49,19 @@ internal static partial class OpenApiV31Deserializer } }, { - "scheme", (o, n, _) => + "scheme", (o, n, _, c) => { o.Scheme = n.GetScalarValue(); } }, { - "bearerFormat", (o, n, _) => + "bearerFormat", (o, n, _, c) => { o.BearerFormat = n.GetScalarValue(); } }, { - "openIdConnectUrl", (o, n, _) => + "openIdConnectUrl", (o, n, _, c) => { var connectUrl = n.GetScalarValue(); if (connectUrl != null) @@ -69,9 +71,9 @@ internal static partial class OpenApiV31Deserializer } }, { - "flows", (o, n, t) => + "flows", (o, n, t, c) => { - o.Flows = LoadOAuthFlows(n, t); + o.Flows = LoadOAuthFlows(n, t, c); } } }; @@ -79,7 +81,7 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _securitySchemePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => { if (p.Equals("x-oai-deprecated", StringComparison.OrdinalIgnoreCase)) { @@ -91,29 +93,26 @@ internal static partial class OpenApiV31Deserializer } else { - o.AddExtension(p, LoadExtension(p,n)); + o.AddExtension(p, LoadExtension(p, n, c)); } }} }; - public static IOpenApiSecurityScheme LoadSecurityScheme(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiSecurityScheme LoadSecurityScheme(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("securityScheme"); + var JsonObject = node.CheckMapNode("securityScheme", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var securitySchemeReference = new OpenApiSecuritySchemeReference(reference.Item1, hostDocument, reference.Item2); - securitySchemeReference.Reference.SetMetadataFromMapNode(mapNode); + securitySchemeReference.Reference.SetMetadataFromJsonObject(JsonObject); return securitySchemeReference; } var securityScheme = new OpenApiSecurityScheme(); - foreach (var property in mapNode) - { - property.ParseField(securityScheme, _securitySchemeFixedFields, _securitySchemePatternFields, hostDocument); - } + ParseMap(JsonObject, securityScheme, _securitySchemeFixedFields, _securitySchemePatternFields, hostDocument, context); return securityScheme; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiServerDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiServerDeserializer.cs index 7fcb13232..294278638 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiServerDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiServerDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V31 @@ -14,28 +16,28 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _serverFixedFields = new() { { - "url", (o, n, _) => + "url", (o, n, _, c) => { o.Url = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - "variables", (o, n, t) => + "variables", (o, n, t, c) => { - o.Variables = n.CreateMap(LoadServerVariable, t); + o.Variables = n.CreateMap(LoadServerVariable, t, c); } } }; private static readonly PatternFieldMap _serverPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => { if (p.Equals("x-oai-name", StringComparison.OrdinalIgnoreCase)) { @@ -43,18 +45,18 @@ internal static partial class OpenApiV31Deserializer } else { - o.AddExtension(p, LoadExtension(p,n)); + o.AddExtension(p, LoadExtension(p, n, c)); } }} }; - public static OpenApiServer LoadServer(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiServer LoadServer(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("server"); + var JsonObject = node.CheckMapNode("server", context); var server = new OpenApiServer(); - ParseMap(mapNode, server, _serverFixedFields, _serverPatternFields, hostDocument); + ParseMap(JsonObject, server, _serverFixedFields, _serverPatternFields, hostDocument, context); return server; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiServerVariableDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiServerVariableDeserializer.cs index 90615a89d..ddff94bcd 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiServerVariableDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiServerVariableDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Linq; @@ -16,19 +18,19 @@ internal static partial class OpenApiV31Deserializer new() { { - "enum", (o, n, doc) => + "enum", (o, n, doc, c) => { - o.Enum = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc).OfType().ToList(); + o.Enum = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc, c).OfType().ToList(); } }, { - "default", (o, n, _) => + "default", (o, n, _, c) => { o.Default = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } @@ -38,16 +40,16 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _serverVariablePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiServerVariable LoadServerVariable(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiServerVariable LoadServerVariable(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("serverVariable"); + var JsonObject = node.CheckMapNode("serverVariable", context); var serverVariable = new OpenApiServerVariable(); - ParseMap(mapNode, serverVariable, _serverVariableFixedFields, _serverVariablePatternFields, hostDocument); + ParseMap(JsonObject, serverVariable, _serverVariableFixedFields, _serverVariablePatternFields, hostDocument, context); return serverVariable; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiTagDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiTagDeserializer.cs index 4504d4de8..3c5fbb2e4 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiTagDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiTagDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V31 @@ -14,21 +16,21 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _tagFixedFields = new() { { - OpenApiConstants.Name, (o, n, _) => + OpenApiConstants.Name, (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { - OpenApiConstants.Description, (o, n, _) => + OpenApiConstants.Description, (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - OpenApiConstants.ExternalDocs, (o, n, t) => + OpenApiConstants.ExternalDocs, (o, n, t, c) => { - o.ExternalDocs = LoadExternalDocs(n, t); + o.ExternalDocs = LoadExternalDocs(n, t, c); } } }; @@ -37,7 +39,7 @@ internal static partial class OpenApiV31Deserializer { { s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), - (o, p, n, doc) => + (o, p, n, doc, c) => { if (p.Equals("x-oas-summary", StringComparison.OrdinalIgnoreCase)) { @@ -57,22 +59,19 @@ internal static partial class OpenApiV31Deserializer } else { - o.AddExtension(p, LoadExtension(p, n)); + o.AddExtension(p, LoadExtension(p, n, c)); } } } }; - public static OpenApiTag LoadTag(ParseNode n, OpenApiDocument hostDocument) + public static OpenApiTag LoadTag(JsonNode n, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = n.CheckMapNode("tag"); + var JsonObject = n.CheckMapNode("tag", context); var domainObject = new OpenApiTag(); - foreach (var propertyNode in mapNode) - { - propertyNode.ParseField(domainObject, _tagFixedFields, _tagPatternFields, hostDocument); - } + ParseMap(JsonObject, domainObject, _tagFixedFields, _tagPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs index 3608ad5f7..36a2f9df5 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; @@ -14,34 +14,27 @@ namespace Microsoft.OpenApi.Reader.V31 internal static partial class OpenApiV31Deserializer { private static void ParseMap( - MapNode? mapNode, + JsonObject? jsonObject, T domainObject, FixedFieldMap fixedFieldMap, PatternFieldMap patternFieldMap, - OpenApiDocument doc) + OpenApiDocument doc, + ParsingContext context) { - if (mapNode == null) - { - return; - } - - foreach (var propertyNode in mapNode) - { - propertyNode.ParseField(domainObject, fixedFieldMap, patternFieldMap, doc); - } - + jsonObject.ParseMap(domainObject, fixedFieldMap, patternFieldMap, doc, context); } private static void ProcessAnyFields( - MapNode mapNode, + JsonObject jsonObject, T domainObject, - AnyFieldMap anyFieldMap) + AnyFieldMap anyFieldMap, + ParsingContext context) { foreach (var anyFieldName in anyFieldMap.Keys.ToList()) { try { - mapNode.Context.StartObject(anyFieldName); + context.StartObject(anyFieldName); var any = anyFieldMap[anyFieldName].PropertyGetter(domainObject); @@ -56,32 +49,33 @@ private static void ProcessAnyFields( } catch (OpenApiException exception) { - exception.Pointer = mapNode.Context.GetLocation(); - mapNode.Context.Diagnostic.Errors.Add(new OpenApiError(exception)); + exception.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new OpenApiError(exception)); } finally { - mapNode.Context.EndObject(); + context.EndObject(); } } } private static void ProcessAnyMapFields( - MapNode mapNode, + JsonObject jsonObject, T domainObject, - AnyMapFieldMap anyMapFieldMap) + AnyMapFieldMap anyMapFieldMap, + ParsingContext context) { foreach (var anyMapFieldName in anyMapFieldMap.Keys.ToList()) { try { - mapNode.Context.StartObject(anyMapFieldName); + context.StartObject(anyMapFieldName); var propertyMapGetter = anyMapFieldMap[anyMapFieldName].PropertyMapGetter(domainObject); if (propertyMapGetter != null) { foreach (var propertyMapElement in propertyMapGetter) { - mapNode.Context.StartObject(propertyMapElement.Key); + context.StartObject(propertyMapElement.Key); if (propertyMapElement.Value != null) { @@ -96,17 +90,17 @@ private static void ProcessAnyMapFields( } catch (OpenApiException exception) { - exception.Pointer = mapNode.Context.GetLocation(); - mapNode.Context.Diagnostic.Errors.Add(new OpenApiError(exception)); + exception.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new OpenApiError(exception)); } finally { - mapNode.Context.EndObject(); + context.EndObject(); } } } - private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(ParseNode node) + private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(JsonNode node) { var value = node.GetScalarValue(); @@ -124,14 +118,14 @@ private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(Parse }; } - public static JsonNode LoadAny(ParseNode node, OpenApiDocument hostDocument) + public static JsonNode LoadAny(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { return node.CreateAny(); } - private static IOpenApiExtension LoadExtension(string name, ParseNode node) + private static IOpenApiExtension LoadExtension(string name, JsonNode node, ParsingContext context) { - if (node.Context.ExtensionParsers is not null && node.Context.ExtensionParsers.TryGetValue(name, out var parser)) + if (context.ExtensionParsers is not null && context.ExtensionParsers.TryGetValue(name, out var parser)) { try { @@ -139,20 +133,20 @@ private static IOpenApiExtension LoadExtension(string name, ParseNode node) } catch (OpenApiException ex) { - ex.Pointer = node.Context.GetLocation(); - node.Context.Diagnostic.Errors.Add(new(ex)); + ex.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new(ex)); } } return new JsonNodeExtension(node.CreateAny()); } - private static string? LoadString(ParseNode node) + private static string? LoadString(JsonNode node) { return node.GetScalarValue(); } - private static bool? LoadBool(ParseNode node) + private static bool? LoadBool(JsonNode node) { var value = node.GetScalarValue(); return value is not null ? bool.Parse(value) : null; diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs index 24a9ba5f2..7e7dbb7af 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Collections.Generic; @@ -20,7 +22,7 @@ public OpenApiV31VersionService(OpenApiDiagnostic diagnostic):base(diagnostic) { } - private readonly Dictionary> _loaders = new Dictionary> + private readonly Dictionary> _loaders = new Dictionary> { [typeof(JsonNodeExtension)] = OpenApiV31Deserializer.LoadAny, [typeof(OpenApiCallback)] = OpenApiV31Deserializer.LoadCallback, @@ -54,11 +56,11 @@ public OpenApiV31VersionService(OpenApiDiagnostic diagnostic):base(diagnostic) [typeof(OpenApiSchemaReference)] = OpenApiV31Deserializer.LoadMapping }; - public override OpenApiDocument LoadDocument(RootNode rootNode, Uri location) + public override OpenApiDocument LoadDocument(JsonNode JsonNode, Uri location, ParsingContext context) { - return OpenApiV31Deserializer.LoadOpenApi(rootNode, location); + return OpenApiV31Deserializer.LoadOpenApi(JsonNode, location, context); } - internal override Dictionary> Loaders => _loaders; + internal override Dictionary> Loaders => _loaders; } } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiXmlDeserializer.cs index f43018714..5071a46c0 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiXmlDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V31 @@ -14,14 +16,14 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _xmlFixedFields = new FixedFieldMap { { - "name", (o, n, _) => + "name", (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { "namespace", - (o, n, _) => + (o, n, _, c) => { var value = n.GetScalarValue(); if (value != null) @@ -32,11 +34,11 @@ internal static partial class OpenApiV31Deserializer }, { "prefix", - (o, n, _) => o.Prefix = n.GetScalarValue() + (o, n, _, c) => o.Prefix = n.GetScalarValue() }, { "attribute", - (o, n, _) => + (o, n, _, c) => { var attribute = n.GetScalarValue(); if (attribute is not null) @@ -49,7 +51,7 @@ internal static partial class OpenApiV31Deserializer }, { "wrapped", - (o, n, _) => + (o, n, _, c) => { var wrapped = n.GetScalarValue(); if (wrapped is not null) @@ -65,18 +67,15 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _xmlPatternFields = new PatternFieldMap { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiXml LoadXml(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiXml LoadXml(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("xml"); + var JsonObject = node.CheckMapNode("xml", context); var xml = new OpenApiXml(); - foreach (var property in mapNode) - { - property.ParseField(xml, _xmlFixedFields, _xmlPatternFields, hostDocument); - } + ParseMap(JsonObject, xml, _xmlFixedFields, _xmlPatternFields, hostDocument, context); return xml; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiCallbackDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiCallbackDeserializer.cs index c3510d8bd..6b03fbdbe 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiCallbackDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiCallbackDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -14,25 +15,25 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _callbackPatternFields = new() { - {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t) => o.AddPathItem(RuntimeExpression.Build(p), LoadPathItem(n, t))}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, + {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t, c) => o.AddPathItem(RuntimeExpression.Build(p), LoadPathItem(n, t, c))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))}, }; - public static IOpenApiCallback LoadCallback(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiCallback LoadCallback(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("callback"); + var JsonObject = node.CheckMapNode("callback", context); - if (mapNode.GetReferencePointer() is { } pointer) + if (JsonObject.GetReferencePointer() is { } pointer) { var reference = GetReferenceIdAndExternalResource(pointer); var callbackReference = new OpenApiCallbackReference(reference.Item1, hostDocument, reference.Item2); - callbackReference.Reference.SetMetadataFromMapNode(mapNode); + callbackReference.Reference.SetMetadataFromJsonObject(JsonObject); return callbackReference; } var domainObject = new OpenApiCallback(); - ParseMap(mapNode, domainObject, _callbackFixedFields, _callbackPatternFields, hostDocument); + ParseMap(JsonObject, domainObject, _callbackFixedFields, _callbackPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiComponentsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiComponentsDeserializer.cs index 761faf472..e11955784 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiComponentsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiComponentsDeserializer.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V32 @@ -13,31 +15,31 @@ internal static partial class OpenApiV32Deserializer { private static readonly FixedFieldMap _componentsFixedFields = new() { - {"schemas", (o, n, t) => o.Schemas = n.CreateMap(LoadSchema, t)}, - {"responses", (o, n, t) => o.Responses = n.CreateMap(LoadResponse, t)}, - {"parameters", (o, n, t) => o.Parameters = n.CreateMap(LoadParameter, t)}, - {"examples", (o, n, t) => o.Examples = n.CreateMap(LoadExample, t)}, - {"requestBodies", (o, n, t) => o.RequestBodies = n.CreateMap(LoadRequestBody, t)}, - {"headers", (o, n, t) => o.Headers = n.CreateMap(LoadHeader, t)}, - {"securitySchemes", (o, n, t) => o.SecuritySchemes = n.CreateMap(LoadSecurityScheme, t)}, - {"links", (o, n, t) => o.Links = n.CreateMap(LoadLink, t)}, - {"callbacks", (o, n, t) => o.Callbacks = n.CreateMap(LoadCallback, t)}, - {"pathItems", (o, n, t) => o.PathItems = n.CreateMap(LoadPathItem, t)}, - {"mediaTypes", (o, n, t) => o.MediaTypes = n.CreateMap(LoadMediaType, t)} + {"schemas", (o, n, t, c) => o.Schemas = n.CreateMap(LoadSchema, t, c)}, + {"responses", (o, n, t, c) => o.Responses = n.CreateMap(LoadResponse, t, c)}, + {"parameters", (o, n, t, c) => o.Parameters = n.CreateMap(LoadParameter, t, c)}, + {"examples", (o, n, t, c) => o.Examples = n.CreateMap(LoadExample, t, c)}, + {"requestBodies", (o, n, t, c) => o.RequestBodies = n.CreateMap(LoadRequestBody, t, c)}, + {"headers", (o, n, t, c) => o.Headers = n.CreateMap(LoadHeader, t, c)}, + {"securitySchemes", (o, n, t, c) => o.SecuritySchemes = n.CreateMap(LoadSecurityScheme, t, c)}, + {"links", (o, n, t, c) => o.Links = n.CreateMap(LoadLink, t, c)}, + {"callbacks", (o, n, t, c) => o.Callbacks = n.CreateMap(LoadCallback, t, c)}, + {"pathItems", (o, n, t, c) => o.PathItems = n.CreateMap(LoadPathItem, t, c)}, + {"mediaTypes", (o, n, t, c) => o.MediaTypes = n.CreateMap(LoadMediaType, t, c)} }; private static readonly PatternFieldMap _componentsPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiComponents LoadComponents(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiComponents LoadComponents(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("components"); + var JsonObject = node.CheckMapNode("components", context); var components = new OpenApiComponents(); - ParseMap(mapNode, components, _componentsFixedFields, _componentsPatternFields, hostDocument); + ParseMap(JsonObject, components, _componentsFixedFields, _componentsPatternFields, hostDocument, context); return components; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiContactDeserializer.cs index d0d6493e7..478dcc224 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiContactDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -11,20 +12,20 @@ internal static partial class OpenApiV32Deserializer private static readonly FixedFieldMap _contactFixedFields = new() { { - "name", (o, n, _) => + "name", (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { - "email", (o, n, _) => + "email", (o, n, _, c) => { o.Email = n.GetScalarValue(); } }, { "url", - (o, n, t) => + (o, n, t, c) => { var url = n.GetScalarValue(); if (url != null) @@ -37,15 +38,15 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _contactPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiContact LoadContact(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiContact LoadContact(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node as MapNode; + var JsonObject = node as JsonObject; var contact = new OpenApiContact(); - ParseMap(mapNode, contact, _contactFixedFields, _contactPatternFields, hostDocument); + ParseMap(JsonObject, contact, _contactFixedFields, _contactPatternFields, hostDocument, context); return contact; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiDiscriminatorDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiDiscriminatorDeserializer.cs index bb0383968..e310c6f4b 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiDiscriminatorDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiDiscriminatorDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -12,21 +13,21 @@ internal static partial class OpenApiV32Deserializer new() { { - "propertyName", (o, n, _) => + "propertyName", (o, n, _, c) => { o.PropertyName = n.GetScalarValue(); } }, { - "mapping", (o, n, doc) => + "mapping", (o, n, doc, c) => { - o.Mapping = n.CreateSimpleMap((node) => LoadMapping(node, doc)); + o.Mapping = n.CreateSimpleMap(node => LoadMapping(node, doc, c), c); } }, { - "defaultMapping", (o, n, doc) => + "defaultMapping", (o, n, doc, c) => { - o.DefaultMapping = LoadMapping(n, doc); + o.DefaultMapping = LoadMapping(n, doc, c); } } }; @@ -34,23 +35,20 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _discriminatorPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiDiscriminator LoadDiscriminator(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiDiscriminator LoadDiscriminator(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("discriminator"); + var JsonObject = node.CheckMapNode("discriminator", context); var discriminator = new OpenApiDiscriminator(); - foreach (var property in mapNode) - { - property.ParseField(discriminator, _discriminatorFixedFields, _discriminatorPatternFields, hostDocument); - } + ParseMap(JsonObject, discriminator, _discriminatorFixedFields, _discriminatorPatternFields, hostDocument, context); return discriminator; } - public static OpenApiSchemaReference LoadMapping(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiSchemaReference LoadMapping(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { var pointer = node.GetScalarValue() ?? throw new InvalidOperationException("Could not get a pointer reference"); var reference = GetReferenceIdAndExternalResource(pointer); diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiDocumentDeserializer.cs index 67e6f1fc7..9edce440e 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiDocumentDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; using System.Collections.Generic; namespace Microsoft.OpenApi.Reader.V32 @@ -12,37 +13,37 @@ internal static partial class OpenApiV32Deserializer private static readonly FixedFieldMap _openApiFixedFields = new() { { - "openapi", (o, n, _) => + "openapi", (o, n, _, c) => { } /* Version is valid field but we already parsed it */ }, - {"info", (o, n, _) => o.Info = LoadInfo(n, o)}, - {"jsonSchemaDialect", (o, n, _) => { if (n.GetScalarValue() is string {} sjsd && Uri.TryCreate(sjsd, UriKind.Absolute, out var jsd)) {o.JsonSchemaDialect = jsd;}} }, - {"$self", (o, n, _) => { if (n.GetScalarValue() is string {} sself && Uri.TryCreate(sself, UriKind.Absolute, out var self)) {o.Self = self;}} }, - {"servers", (o, n, _) => o.Servers = n.CreateList(LoadServer, o)}, - {"paths", (o, n, _) => o.Paths = LoadPaths(n, o)}, - {"webhooks", (o, n, _) => o.Webhooks = n.CreateMap(LoadPathItem, o)}, - {"components", (o, n, _) => o.Components = LoadComponents(n, o)}, - {"tags", (o, n, _) => { if (n.CreateList(LoadTag, o) is {Count:> 0} tags) {o.Tags = new HashSet(tags, OpenApiTagComparer.Instance); } } }, - {"externalDocs", (o, n, _) => o.ExternalDocs = LoadExternalDocs(n, o)}, - {"security", (o, n, _) => o.Security = n.CreateList(LoadSecurityRequirement, o)} + {"info", (o, n, _, c) => o.Info = LoadInfo(n, o, c)}, + {"jsonSchemaDialect", (o, n, _, c) => { if (n.GetScalarValue() is string {} sjsd && Uri.TryCreate(sjsd, UriKind.Absolute, out var jsd)) {o.JsonSchemaDialect = jsd;}} }, + {"$self", (o, n, _, c) => { if (n.GetScalarValue() is string {} sself && Uri.TryCreate(sself, UriKind.Absolute, out var self)) {o.Self = self;}} }, + {"servers", (o, n, _, c) => o.Servers = n.CreateList(LoadServer, o, c)}, + {"paths", (o, n, _, c) => o.Paths = LoadPaths(n, o, c)}, + {"webhooks", (o, n, _, c) => o.Webhooks = n.CreateMap(LoadPathItem, o, c)}, + {"components", (o, n, _, c) => o.Components = LoadComponents(n, o, c)}, + {"tags", (o, n, _, c) => { if (n.CreateList(LoadTag, o, c) is {Count:> 0} tags) {o.Tags = new HashSet(tags, OpenApiTagComparer.Instance); } } }, + {"externalDocs", (o, n, _, c) => o.ExternalDocs = LoadExternalDocs(n, o, c)}, + {"security", (o, n, _, c) => o.Security = n.CreateList(LoadSecurityRequirement, o, c)} }; private static readonly PatternFieldMap _openApiPatternFields = new() { // We have no semantics to verify X- nodes, therefore treat them as just values. - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiDocument LoadOpenApi(RootNode rootNode, Uri location) + public static OpenApiDocument LoadOpenApi(JsonNode JsonNode, Uri location, ParsingContext context) { var openApiDoc = new OpenApiDocument { BaseUri = location }; - var openApiNode = rootNode.GetMap(); + var openApiNode = JsonNode.CheckMapNode("OpenAPI", context); - ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, openApiDoc); + ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, openApiDoc, context); // Register components openApiDoc.Workspace?.RegisterComponents(openApiDoc); diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiEncodingDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiEncodingDeserializer.cs index 8f2777961..74630ba82 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiEncodingDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiEncodingDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -11,39 +12,39 @@ internal static partial class OpenApiV32Deserializer private static readonly FixedFieldMap _encodingFixedFields = new() { { - "contentType", (o, n, _) => + "contentType", (o, n, _, c) => { o.ContentType = n.GetScalarValue(); } }, { - "headers", (o, n, t) => + "headers", (o, n, t, c) => { - o.Headers = n.CreateMap(LoadHeader, t); + o.Headers = n.CreateMap(LoadHeader, t, c); } }, { - "encoding", (o, n, t) => + "encoding", (o, n, t, c) => { - o.Encoding = n.CreateMap(LoadEncoding, t); + o.Encoding = n.CreateMap(LoadEncoding, t, c); } }, { - "itemEncoding", (o, n, t) => + "itemEncoding", (o, n, t, c) => { - o.ItemEncoding = LoadEncoding(n, t); + o.ItemEncoding = LoadEncoding(n, t, c); } }, { - "prefixEncoding", (o, n, t) => + "prefixEncoding", (o, n, t, c) => { - o.PrefixEncoding = n.CreateList(LoadEncoding, t); + o.PrefixEncoding = n.CreateList(LoadEncoding, t, c); } }, { - "style", (o, n, _) => + "style", (o, n, _, c) => { - if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + if(!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var style)) { return; } @@ -51,7 +52,7 @@ internal static partial class OpenApiV32Deserializer } }, { - "explode", (o, n, _) => + "explode", (o, n, _, c) => { var explode = n.GetScalarValue(); if (explode is not null) @@ -61,7 +62,7 @@ internal static partial class OpenApiV32Deserializer } }, { - "allowReserved", (o, n, _) => + "allowReserved", (o, n, _, c) => { var allowReserved = n.GetScalarValue(); if (allowReserved is not null) @@ -75,18 +76,15 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _encodingPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiEncoding LoadEncoding(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiEncoding LoadEncoding(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("encoding"); + var JsonObject = node.CheckMapNode("encoding", context); var encoding = new OpenApiEncoding(); - foreach (var property in mapNode) - { - property.ParseField(encoding, _encodingFixedFields, _encodingPatternFields, hostDocument); - } + ParseMap(JsonObject, encoding, _encodingFixedFields, _encodingPatternFields, hostDocument, context); return encoding; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiExampleDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiExampleDeserializer.cs index 81a89af56..2af74a472 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiExampleDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiExampleDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -11,37 +12,37 @@ internal static partial class OpenApiV32Deserializer private static readonly FixedFieldMap _exampleFixedFields = new() { { - "summary", (o, n, _) => + "summary", (o, n, _, c) => { o.Summary = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - "value", (o, n, _) => + "value", (o, n, _, c) => { o.Value = n.CreateAny(); } }, { - "externalValue", (o, n, _) => + "externalValue", (o, n, _, c) => { o.ExternalValue = n.GetScalarValue(); } }, { - "dataValue", (o, n, _) => + "dataValue", (o, n, _, c) => { o.DataValue = n.CreateAny(); } }, { - "serializedValue", (o, n, _) => + "serializedValue", (o, n, _, c) => { o.SerializedValue = n.GetScalarValue(); } @@ -52,27 +53,24 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _examplePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiExample LoadExample(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiExample LoadExample(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("example"); + var JsonObject = node.CheckMapNode("example", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var exampleReference = new OpenApiExampleReference(reference.Item1, hostDocument, reference.Item2); - exampleReference.Reference.SetMetadataFromMapNode(mapNode); + exampleReference.Reference.SetMetadataFromJsonObject(JsonObject); return exampleReference; } var example = new OpenApiExample(); - foreach (var property in mapNode) - { - property.ParseField(example, _exampleFixedFields, _examplePatternFields, hostDocument); - } + ParseMap(JsonObject, example, _exampleFixedFields, _examplePatternFields, hostDocument, context); return example; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiExternalDocsDeserializer.cs index 46325d6bb..8f16ba989 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiExternalDocsDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -13,14 +14,14 @@ internal static partial class OpenApiV32Deserializer { // $ref { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { "url", - (o, n, t) => + (o, n, t, c) => { var url = n.GetScalarValue(); if (url != null) @@ -35,16 +36,16 @@ internal static partial class OpenApiV32Deserializer new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiExternalDocs LoadExternalDocs(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiExternalDocs LoadExternalDocs(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("externalDocs"); + var JsonObject = node.CheckMapNode("externalDocs", context); var externalDocs = new OpenApiExternalDocs(); - ParseMap(mapNode, externalDocs, _externalDocsFixedFields, _externalDocsPatternFields, hostDocument); + ParseMap(JsonObject, externalDocs, _externalDocsFixedFields, _externalDocsPatternFields, hostDocument, context); return externalDocs; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiHeaderDeserializer.cs index ab614f91f..5baa14a33 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiHeaderDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -11,14 +12,14 @@ internal static partial class OpenApiV32Deserializer private static readonly FixedFieldMap _headerFixedFields = new() { { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { "required", - (o, n, _) => + (o, n, _, c) => { var required = n.GetScalarValue(); if (required != null) @@ -29,7 +30,7 @@ internal static partial class OpenApiV32Deserializer }, { "deprecated", - (o, n, _) => + (o, n, _, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -40,7 +41,7 @@ internal static partial class OpenApiV32Deserializer }, { "allowEmptyValue", - (o, n, _) => + (o, n, _, c) => { var allowEmptyVal = n.GetScalarValue(); if (allowEmptyVal != null) @@ -51,7 +52,7 @@ internal static partial class OpenApiV32Deserializer }, { "allowReserved", - (o, n, _) => + (o, n, _, c) => { var allowReserved = n.GetScalarValue(); if (allowReserved != null) @@ -61,9 +62,9 @@ internal static partial class OpenApiV32Deserializer } }, { - "style", (o, n, _) => + "style", (o, n, _, c) => { - if(!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + if(!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var style)) { return; } @@ -72,7 +73,7 @@ internal static partial class OpenApiV32Deserializer }, { "explode", - (o, n, _) => + (o, n, _, c) => { var explode = n.GetScalarValue(); if (explode != null) @@ -82,25 +83,25 @@ internal static partial class OpenApiV32Deserializer } }, { - "schema", (o, n, t) => + "schema", (o, n, t, c) => { - o.Schema = LoadSchema(n, t); + o.Schema = LoadSchema(n, t, c); } }, { - "content", (o, n, t) => + "content", (o, n, t, c) => { - o.Content = n.CreateMap(LoadMediaType, t); + o.Content = n.CreateMap(LoadMediaType, t, c); } }, { - "examples", (o, n, t) => + "examples", (o, n, t, c) => { - o.Examples = n.CreateMap(LoadExample, t); + o.Examples = n.CreateMap(LoadExample, t, c); } }, { - "example", (o, n, _) => + "example", (o, n, _, c) => { o.Example = n.CreateAny(); } @@ -109,27 +110,24 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _headerPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiHeader LoadHeader(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiHeader LoadHeader(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("header"); + var JsonObject = node.CheckMapNode("header", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var headerReference = new OpenApiHeaderReference(reference.Item1, hostDocument, reference.Item2); - headerReference.Reference.SetMetadataFromMapNode(mapNode); + headerReference.Reference.SetMetadataFromJsonObject(JsonObject); return headerReference; } var header = new OpenApiHeader(); - foreach (var property in mapNode) - { - property.ParseField(header, _headerFixedFields, _headerPatternFields, hostDocument); - } + ParseMap(JsonObject, header, _headerFixedFields, _headerPatternFields, hostDocument, context); return header; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiInfoDeserializer.cs index e0426a2ac..f0c427276 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiInfoDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -11,32 +12,32 @@ internal static partial class OpenApiV32Deserializer public static readonly FixedFieldMap InfoFixedFields = new() { { - "title", (o, n, _) => + "title", (o, n, _, c) => { o.Title = n.GetScalarValue(); } }, { - "version", (o, n, _) => + "version", (o, n, _, c) => { o.Version = n.GetScalarValue(); } }, { - "summary", (o, n, _) => + "summary", (o, n, _, c) => { o.Summary = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { "termsOfService", - (o, n, _) => + (o, n, _, c) => { var terms = n.GetScalarValue(); if (terms != null) @@ -46,29 +47,29 @@ internal static partial class OpenApiV32Deserializer } }, { - "contact", (o, n, t) => + "contact", (o, n, t, c) => { - o.Contact = LoadContact(n, t); + o.Contact = LoadContact(n, t, c); } }, { - "license", (o, n, t) => + "license", (o, n, t, c) => { - o.License = LoadLicense(n, t); + o.License = LoadLicense(n, t, c); } } }; public static readonly PatternFieldMap InfoPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, k, n, _) => o.AddExtension(k,LoadExtension(k, n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, k, n, _, c) => o.AddExtension(k,LoadExtension(k, n, c))} }; - public static OpenApiInfo LoadInfo(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiInfo LoadInfo(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Info"); + var JsonObject = node.CheckMapNode("Info", context); var info = new OpenApiInfo(); - ParseMap(mapNode, info, InfoFixedFields, InfoPatternFields, hostDocument); + ParseMap(JsonObject, info, InfoFixedFields, InfoPatternFields, hostDocument, context); return info; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiLicenseDeserializer.cs index 59376695f..a971fb727 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiLicenseDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -11,20 +12,20 @@ internal static partial class OpenApiV32Deserializer private static readonly FixedFieldMap _licenseFixedFields = new() { { - "name", (o, n, _) => + "name", (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { - "identifier", (o, n, _) => + "identifier", (o, n, _, c) => { o.Identifier = n.GetScalarValue(); } }, { "url", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -37,16 +38,16 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _licensePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - internal static OpenApiLicense LoadLicense(ParseNode node, OpenApiDocument hostDocument) + internal static OpenApiLicense LoadLicense(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("License"); + var JsonObject = node.CheckMapNode("License", context); var license = new OpenApiLicense(); - ParseMap(mapNode, license, _licenseFixedFields, _licensePatternFields, hostDocument); + ParseMap(JsonObject, license, _licenseFixedFields, _licensePatternFields, hostDocument, context); return license; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiLinkDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiLinkDeserializer.cs index c926b447e..6bfeb02cd 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiLinkDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiLinkDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -11,58 +12,58 @@ internal static partial class OpenApiV32Deserializer private static readonly FixedFieldMap _linkFixedFields = new() { { - "operationRef", (o, n, _) => + "operationRef", (o, n, _, c) => { o.OperationRef = n.GetScalarValue(); } }, { - "operationId", (o, n, _) => + "operationId", (o, n, _, c) => { o.OperationId = n.GetScalarValue(); } }, { - "parameters", (o, n, _) => + "parameters", (o, n, _, c) => { - o.Parameters = n.CreateSimpleMap(LoadRuntimeExpressionAnyWrapper); + o.Parameters = n.CreateSimpleMap(LoadRuntimeExpressionAnyWrapper, c); } }, { - "requestBody", (o, n, _) => + "requestBody", (o, n, _, c) => { o.RequestBody = LoadRuntimeExpressionAnyWrapper(n); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, - {"server", (o, n, t) => o.Server = LoadServer(n, t)} + {"server", (o, n, t, c) => o.Server = LoadServer(n, t, c)} }; private static readonly PatternFieldMap _linkPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))}, }; - public static IOpenApiLink LoadLink(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiLink LoadLink(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("link"); + var JsonObject = node.CheckMapNode("link", context); var link = new OpenApiLink(); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var linkReference = new OpenApiLinkReference(reference.Item1, hostDocument, reference.Item2); - linkReference.Reference.SetMetadataFromMapNode(mapNode); + linkReference.Reference.SetMetadataFromJsonObject(JsonObject); return linkReference; } - ParseMap(mapNode, link, _linkFixedFields, _linkPatternFields, hostDocument); + ParseMap(JsonObject, link, _linkFixedFields, _linkPatternFields, hostDocument, context); return link; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiMediaTypeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiMediaTypeDeserializer.cs index c57fccb8c..e65adc0de 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiMediaTypeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiMediaTypeDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -12,45 +13,45 @@ internal static partial class OpenApiV32Deserializer new() { { - OpenApiConstants.Schema, (o, n, t) => + OpenApiConstants.Schema, (o, n, t, c) => { - o.Schema = LoadSchema(n, t); + o.Schema = LoadSchema(n, t, c); } }, { - OpenApiConstants.ItemSchema, (o, n, t) => + OpenApiConstants.ItemSchema, (o, n, t, c) => { - o.ItemSchema = LoadSchema(n, t); + o.ItemSchema = LoadSchema(n, t, c); } }, { - OpenApiConstants.Examples, (o, n, t) => + OpenApiConstants.Examples, (o, n, t, c) => { - o.Examples = n.CreateMap(LoadExample, t); + o.Examples = n.CreateMap(LoadExample, t, c); } }, { - OpenApiConstants.Example, (o, n, _) => + OpenApiConstants.Example, (o, n, _, c) => { o.Example = n.CreateAny(); } }, { - OpenApiConstants.Encoding, (o, n, t) => + OpenApiConstants.Encoding, (o, n, t, c) => { - o.Encoding = n.CreateMap(LoadEncoding, t); + o.Encoding = n.CreateMap(LoadEncoding, t, c); } }, { - OpenApiConstants.ItemEncoding, (o, n, t) => + OpenApiConstants.ItemEncoding, (o, n, t, c) => { - o.ItemEncoding = LoadEncoding(n, t); + o.ItemEncoding = LoadEncoding(n, t, c); } }, { - OpenApiConstants.PrefixEncoding, (o, n, t) => + OpenApiConstants.PrefixEncoding, (o, n, t, c) => { - o.PrefixEncoding = n.CreateList(LoadEncoding, t); + o.PrefixEncoding = n.CreateList(LoadEncoding, t, c); } }, }; @@ -58,7 +59,7 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _mediaTypePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; private static readonly AnyFieldMap _mediaTypeAnyFields = new AnyFieldMap @@ -86,25 +87,25 @@ internal static partial class OpenApiV32Deserializer } }; - public static IOpenApiMediaType LoadMediaType(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiMediaType LoadMediaType(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode(OpenApiConstants.Content); + var JsonObject = node.CheckMapNode(OpenApiConstants.Content, context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var mediaTypeReference = new OpenApiMediaTypeReference(reference.Item1, hostDocument, reference.Item2); - mediaTypeReference.Reference.SetMetadataFromMapNode(mapNode); + mediaTypeReference.Reference.SetMetadataFromJsonObject(JsonObject); return mediaTypeReference; } var mediaType = new OpenApiMediaType(); - ParseMap(mapNode, mediaType, _mediaTypeFixedFields, _mediaTypePatternFields, hostDocument); + ParseMap(JsonObject, mediaType, _mediaTypeFixedFields, _mediaTypePatternFields, hostDocument, context); - ProcessAnyFields(mapNode, mediaType, _mediaTypeAnyFields); - ProcessAnyMapFields(mapNode, mediaType, _mediaTypeAnyMapOpenApiExampleFields); + ProcessAnyFields(JsonObject, mediaType, _mediaTypeAnyFields, context); + ProcessAnyMapFields(JsonObject, mediaType, _mediaTypeAnyMapOpenApiExampleFields, context); return mediaType; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiOAuthFlowDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiOAuthFlowDeserializer.cs index a0006cbf4..405674872 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiOAuthFlowDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiOAuthFlowDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; using System.Linq; namespace Microsoft.OpenApi.Reader.V32 @@ -14,7 +15,7 @@ internal static partial class OpenApiV32Deserializer { { "authorizationUrl", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -25,7 +26,7 @@ internal static partial class OpenApiV32Deserializer }, { "tokenUrl", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -36,7 +37,7 @@ internal static partial class OpenApiV32Deserializer }, { "refreshUrl", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -47,7 +48,7 @@ internal static partial class OpenApiV32Deserializer }, { "deviceAuthorizationUrl", - (o, n, _) => + (o, n, _, c) => { var url = n.GetScalarValue(); if (url != null) @@ -56,24 +57,21 @@ internal static partial class OpenApiV32Deserializer } } }, - {"scopes", (o, n, _) => o.Scopes = n.CreateSimpleMap(LoadString).Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value!)} + {"scopes", (o, n, _, c) => o.Scopes = n.CreateSimpleMap(LoadString, c).Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value!)} }; private static readonly PatternFieldMap _oAuthFlowPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiOAuthFlow LoadOAuthFlow(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiOAuthFlow LoadOAuthFlow(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("OAuthFlow"); + var JsonObject = node.CheckMapNode("OAuthFlow", context); var oauthFlow = new OpenApiOAuthFlow(); - foreach (var property in mapNode) - { - property.ParseField(oauthFlow, _oAuthFlowFixedFileds, _oAuthFlowPatternFields, hostDocument); - } + ParseMap(JsonObject, oauthFlow, _oAuthFlowFixedFileds, _oAuthFlowPatternFields, hostDocument, context); return oauthFlow; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiOAuthFlowsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiOAuthFlowsDeserializer.cs index 99f0fafca..3ddf212fc 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiOAuthFlowsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiOAuthFlowsDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -11,28 +12,25 @@ internal static partial class OpenApiV32Deserializer private static readonly FixedFieldMap _oAuthFlowsFixedFields = new() { - {"implicit", (o, n, t) => o.Implicit = LoadOAuthFlow(n, t)}, - {"password", (o, n, t) => o.Password = LoadOAuthFlow(n, t)}, - {"clientCredentials", (o, n, t) => o.ClientCredentials = LoadOAuthFlow(n, t)}, - {"authorizationCode", (o, n, t) => o.AuthorizationCode = LoadOAuthFlow(n, t)}, - {"deviceAuthorization", (o, n, t) => o.DeviceAuthorization = LoadOAuthFlow(n, t)} + {"implicit", (o, n, t, c) => o.Implicit = LoadOAuthFlow(n, t, c)}, + {"password", (o, n, t, c) => o.Password = LoadOAuthFlow(n, t, c)}, + {"clientCredentials", (o, n, t, c) => o.ClientCredentials = LoadOAuthFlow(n, t, c)}, + {"authorizationCode", (o, n, t, c) => o.AuthorizationCode = LoadOAuthFlow(n, t, c)}, + {"deviceAuthorization", (o, n, t, c) => o.DeviceAuthorization = LoadOAuthFlow(n, t, c)} }; private static readonly PatternFieldMap _oAuthFlowsPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiOAuthFlows LoadOAuthFlows(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiOAuthFlows LoadOAuthFlows(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("OAuthFlows"); + var JsonObject = node.CheckMapNode("OAuthFlows", context); var oAuthFlows = new OpenApiOAuthFlows(); - foreach (var property in mapNode) - { - property.ParseField(oAuthFlows, _oAuthFlowsFixedFields, _oAuthFlowsPatternFields, hostDocument); - } + ParseMap(JsonObject, oAuthFlows, _oAuthFlowsFixedFields, _oAuthFlowsPatternFields, hostDocument, context); return oAuthFlows; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiOperationDeserializer.cs index 370731bd5..a61c1b01c 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiOperationDeserializer.cs @@ -15,16 +15,17 @@ internal static partial class OpenApiV32Deserializer new() { { - "tags", (o, n, doc) => { + "tags", (o, n, doc, c) => { if (n.CreateSimpleList( - (valueNode, doc) => + (jsonNode, document) => { - var val = valueNode.GetScalarValue(); + var val = jsonNode.GetScalarValue(); if (string.IsNullOrEmpty(val)) return null; // Avoid exception on empty tag, we'll remove these from the list further on - return LoadTagByReference(val , doc); - }, - doc) + return LoadTagByReference(val!, document); + }, + doc, + c) // Filter out empty tags instead of excepting on them .OfType().ToList() is {Count: > 0} tags) { @@ -33,56 +34,56 @@ internal static partial class OpenApiV32Deserializer } }, { - "summary", (o, n, _) => + "summary", (o, n, _, c) => { o.Summary = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - "externalDocs", (o, n, t) => + "externalDocs", (o, n, t, c) => { - o.ExternalDocs = LoadExternalDocs(n, t); + o.ExternalDocs = LoadExternalDocs(n, t, c); } }, { - "operationId", (o, n, _) => + "operationId", (o, n, _, c) => { o.OperationId = n.GetScalarValue(); } }, { - "parameters", (o, n, t) => + "parameters", (o, n, t, c) => { - o.Parameters = n.CreateList(LoadParameter, t); + o.Parameters = n.CreateList(LoadParameter, t, c); } }, { - "requestBody", (o, n, t) => + "requestBody", (o, n, t, c) => { - o.RequestBody = LoadRequestBody(n, t); + o.RequestBody = LoadRequestBody(n, t, c); } }, { - "responses", (o, n, t) => + "responses", (o, n, t, c) => { - o.Responses = LoadResponses(n, t); + o.Responses = LoadResponses(n, t, c); } }, { - "callbacks", (o, n, t) => + "callbacks", (o, n, t, c) => { - o.Callbacks = n.CreateMap(LoadCallback, t); + o.Callbacks = n.CreateMap(LoadCallback, t, c); } }, { "deprecated", - (o, n, _) => + (o, n, _, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -92,18 +93,18 @@ internal static partial class OpenApiV32Deserializer } }, { - "security", (o, n, t) => + "security", (o, n, t, c) => { - if (n.JsonNode is JsonArray) + if (n is JsonArray) { - o.Security = n.CreateList(LoadSecurityRequirement, t); + o.Security = n.CreateList(LoadSecurityRequirement, t, c); } } }, { - "servers", (o, n, t) => + "servers", (o, n, t, c) => { - o.Servers = n.CreateList(LoadServer, t); + o.Servers = n.CreateList(LoadServer, t, c); } }, }; @@ -111,16 +112,16 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _operationPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))}, }; - internal static OpenApiOperation LoadOperation(ParseNode node, OpenApiDocument hostDocument) + internal static OpenApiOperation LoadOperation(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Operation"); + var JsonObject = node.CheckMapNode("Operation", context); var operation = new OpenApiOperation(); - ParseMap(mapNode, operation, _operationFixedFields, _operationPatternFields, hostDocument); + ParseMap(JsonObject, operation, _operationFixedFields, _operationPatternFields, hostDocument, context); return operation; } @@ -132,4 +133,3 @@ private static OpenApiTagReference LoadTagByReference(string tagName, OpenApiDoc } } } - diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiParameterDeserializer.cs index 0cdb4a7bd..773467889 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiParameterDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -12,15 +13,15 @@ internal static partial class OpenApiV32Deserializer new() { { - "name", (o, n, _) => + "name", (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { - "in", (o, n, _) => + "in", (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var _in)) { return; } @@ -28,14 +29,14 @@ internal static partial class OpenApiV32Deserializer } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { "required", - (o, n, t) => + (o, n, t, c) => { var required = n.GetScalarValue(); if (required != null) @@ -46,7 +47,7 @@ internal static partial class OpenApiV32Deserializer }, { "deprecated", - (o, n, t) => + (o, n, t, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -57,7 +58,7 @@ internal static partial class OpenApiV32Deserializer }, { "allowEmptyValue", - (o, n, t) => + (o, n, t, c) => { var allowEmptyValue = n.GetScalarValue(); if (allowEmptyValue != null) @@ -68,7 +69,7 @@ internal static partial class OpenApiV32Deserializer }, { "allowReserved", - (o, n, _) => + (o, n, _, c) => { var allowReserved = n.GetScalarValue(); if (allowReserved != null) @@ -78,9 +79,9 @@ internal static partial class OpenApiV32Deserializer } }, { - "style", (o, n, _) => + "style", (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var style)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var style)) { return; } @@ -88,7 +89,7 @@ internal static partial class OpenApiV32Deserializer } }, { - "explode", (o, n, _) => + "explode", (o, n, _, c) => { var explode = n.GetScalarValue(); if (explode != null) @@ -98,25 +99,25 @@ internal static partial class OpenApiV32Deserializer } }, { - "schema", (o, n, t) => + "schema", (o, n, t, c) => { - o.Schema = LoadSchema(n, t); + o.Schema = LoadSchema(n, t, c); } }, { - "content", (o, n, t) => + "content", (o, n, t, c) => { - o.Content = n.CreateMap(LoadMediaType, t); + o.Content = n.CreateMap(LoadMediaType, t, c); } }, { - "examples", (o, n, t) => + "examples", (o, n, t, c) => { - o.Examples = n.CreateMap(LoadExample, t); + o.Examples = n.CreateMap(LoadExample, t, c); } }, { - "example", (o, n, _) => + "example", (o, n, _, c) => { o.Example = n.CreateAny(); } @@ -126,7 +127,7 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _parameterPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; private static readonly AnyFieldMap _parameterAnyFields = new AnyFieldMap @@ -153,24 +154,24 @@ internal static partial class OpenApiV32Deserializer } }; - public static IOpenApiParameter LoadParameter(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiParameter LoadParameter(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("parameter"); + var JsonObject = node.CheckMapNode("parameter", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var parameterReference = new OpenApiParameterReference(reference.Item1, hostDocument, reference.Item2); - parameterReference.Reference.SetMetadataFromMapNode(mapNode); + parameterReference.Reference.SetMetadataFromJsonObject(JsonObject); return parameterReference; } var parameter = new OpenApiParameter(); - ParseMap(mapNode, parameter, _parameterFixedFields, _parameterPatternFields, hostDocument); - ProcessAnyFields(mapNode, parameter, _parameterAnyFields); - ProcessAnyMapFields(mapNode, parameter, _parameterAnyMapOpenApiExampleFields); + ParseMap(JsonObject, parameter, _parameterFixedFields, _parameterPatternFields, hostDocument, context); + ProcessAnyFields(JsonObject, parameter, _parameterAnyFields, context); + ProcessAnyMapFields(JsonObject, parameter, _parameterAnyMapOpenApiExampleFields, context); return parameter; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiPathItemDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiPathItemDeserializer.cs index 9b49d2c9e..9d9087216 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiPathItemDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiPathItemDeserializer.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Text.Json.Nodes; using System.Collections.Generic; using System.Linq; using System.Net.Http; @@ -15,81 +16,80 @@ internal static partial class OpenApiV32Deserializer { { - "summary", (o, n, _) => + "summary", (o, n, _, c) => { o.Summary = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, - {"get", (o, n, t) => o.AddOperation(HttpMethod.Get, LoadOperation(n, t))}, - {"put", (o, n, t) => o.AddOperation(HttpMethod.Put, LoadOperation(n, t))}, - {"post", (o, n, t) => o.AddOperation(HttpMethod.Post, LoadOperation(n, t))}, - {"delete", (o, n, t) => o.AddOperation(HttpMethod.Delete, LoadOperation(n, t))}, - {"options", (o, n, t) => o.AddOperation(HttpMethod.Options, LoadOperation(n, t))}, - {"head", (o, n, t) => o.AddOperation(HttpMethod.Head, LoadOperation(n, t))}, + {"get", (o, n, t, c) => o.AddOperation(HttpMethod.Get, LoadOperation(n, t, c))}, + {"put", (o, n, t, c) => o.AddOperation(HttpMethod.Put, LoadOperation(n, t, c))}, + {"post", (o, n, t, c) => o.AddOperation(HttpMethod.Post, LoadOperation(n, t, c))}, + {"delete", (o, n, t, c) => o.AddOperation(HttpMethod.Delete, LoadOperation(n, t, c))}, + {"options", (o, n, t, c) => o.AddOperation(HttpMethod.Options, LoadOperation(n, t, c))}, + {"head", (o, n, t, c) => o.AddOperation(HttpMethod.Head, LoadOperation(n, t, c))}, #if NETSTANDARD2_1_OR_GREATER - {"patch", (o, n, t) => o.AddOperation(HttpMethod.Patch, LoadOperation(n, t))}, + {"patch", (o, n, t, c) => o.AddOperation(HttpMethod.Patch, LoadOperation(n, t, c))}, #else - {"patch", (o, n, t) => o.AddOperation(new HttpMethod("PATCH"), LoadOperation(n, t))}, + {"patch", (o, n, t, c) => o.AddOperation(new HttpMethod("PATCH"), LoadOperation(n, t, c))}, #endif - {"query", (o, n, t) => o.AddOperation(new HttpMethod("QUERY"), LoadOperation(n, t))}, - {"trace", (o, n, t) => o.AddOperation(HttpMethod.Trace, LoadOperation(n, t))}, - {"servers", (o, n, t) => o.Servers = n.CreateList(LoadServer, t)}, - {"parameters", (o, n, t) => o.Parameters = n.CreateList(LoadParameter, t)}, + {"query", (o, n, t, c) => o.AddOperation(new HttpMethod("QUERY"), LoadOperation(n, t, c))}, + {"trace", (o, n, t, c) => o.AddOperation(HttpMethod.Trace, LoadOperation(n, t, c))}, + {"servers", (o, n, t, c) => o.Servers = n.CreateList(LoadServer, t, c)}, + {"parameters", (o, n, t, c) => o.Parameters = n.CreateList(LoadParameter, t, c)}, {OpenApiConstants.AdditionalOperations, LoadAdditionalOperations } }; - private static void LoadAdditionalOperations(OpenApiPathItem o, ParseNode n, OpenApiDocument t) + private static void LoadAdditionalOperations(OpenApiPathItem o, JsonNode n, OpenApiDocument t, ParsingContext context) { if (n is null) { return; } - var mapNode = n.CheckMapNode(OpenApiConstants.AdditionalOperations); + var JsonObject = n.CheckMapNode(OpenApiConstants.AdditionalOperations, context); - foreach (var property in mapNode.Where(p => !OpenApiPathItem._standardHttp32MethodsNames.Contains(p.Name))) + foreach (var property in JsonObject.Where(p => !OpenApiPathItem._standardHttp32MethodsNames.Contains(p.Key))) { - var operationType = property.Name; + var operationType = property.Key; var httpMethod = new HttpMethod(operationType); - o.AddOperation(httpMethod, LoadOperation(property.Value, t)); + o.AddOperation(httpMethod, LoadOperation(property.Value ?? JsonNullSentinel.JsonNull, t, context)); } } private static readonly PatternFieldMap _pathItemPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiPathItem LoadPathItem(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiPathItem LoadPathItem(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("PathItem"); + var JsonObject = node.CheckMapNode("PathItem", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var pathItemReference = new OpenApiPathItemReference(reference.Item1, hostDocument, reference.Item2); - pathItemReference.Reference.SetMetadataFromMapNode(mapNode); + pathItemReference.Reference.SetMetadataFromJsonObject(JsonObject); return pathItemReference; } var pathItem = new OpenApiPathItem(); - ParseMap(mapNode, pathItem, _pathItemFixedFields, _pathItemPatternFields, hostDocument); + ParseMap(JsonObject, pathItem, _pathItemFixedFields, _pathItemPatternFields, hostDocument, context); return pathItem; } } } - diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiPathsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiPathsDeserializer.cs index 1790553e6..d19e5838f 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiPathsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiPathsDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -12,17 +13,17 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _pathsPatternFields = new() { - {s => s.StartsWith("/", StringComparison.OrdinalIgnoreCase), (o, k, n, t) => o.Add(k, LoadPathItem(n, t))}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith("/", StringComparison.OrdinalIgnoreCase), (o, k, n, t, c) => o.Add(k, LoadPathItem(n, t, c))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiPaths LoadPaths(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiPaths LoadPaths(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Paths"); + var JsonObject = node.CheckMapNode("Paths", context); var domainObject = new OpenApiPaths(); - ParseMap(mapNode, domainObject, _pathsFixedFields, _pathsPatternFields, hostDocument); + ParseMap(JsonObject, domainObject, _pathsFixedFields, _pathsPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiRequestBodyDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiRequestBodyDeserializer.cs index 0dc03c99d..8891fb042 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiRequestBodyDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiRequestBodyDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -12,19 +13,19 @@ internal static partial class OpenApiV32Deserializer new() { { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - "content", (o, n, t) => + "content", (o, n, t, c) => { - o.Content = n.CreateMap(LoadMediaType, t); + o.Content = n.CreateMap(LoadMediaType, t, c); } }, { - "required", (o, n, _) => + "required", (o, n, _, c) => { var required = n.GetScalarValue(); if (required != null) @@ -38,27 +39,24 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _requestBodyPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiRequestBody LoadRequestBody(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiRequestBody LoadRequestBody(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("requestBody"); + var JsonObject = node.CheckMapNode("requestBody", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var requestBodyReference = new OpenApiRequestBodyReference(reference.Item1, hostDocument, reference.Item2); - requestBodyReference.Reference.SetMetadataFromMapNode(mapNode); + requestBodyReference.Reference.SetMetadataFromJsonObject(JsonObject); return requestBodyReference; } var requestBody = new OpenApiRequestBody(); - foreach (var property in mapNode) - { - property.ParseField(requestBody, _requestBodyFixedFields, _requestBodyPatternFields, hostDocument); - } + ParseMap(JsonObject, requestBody, _requestBodyFixedFields, _requestBodyPatternFields, hostDocument, context); return requestBody; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiResponseDeserializer.cs index a6020991b..c8c9df6ad 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiResponseDeserializer.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json.Nodes; namespace Microsoft.OpenApi.Reader.V32 { @@ -11,33 +12,33 @@ internal static partial class OpenApiV32Deserializer private static readonly FixedFieldMap _responseFixedFields = new() { { - "summary", (o, n, _) => + "summary", (o, n, _, c) => { o.Summary = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - "headers", (o, n, t) => + "headers", (o, n, t, c) => { - o.Headers = n.CreateMap(LoadHeader, t); + o.Headers = n.CreateMap(LoadHeader, t, c); } }, { - "content", (o, n, t) => + "content", (o, n, t, c) => { - o.Content = n.CreateMap(LoadMediaType, t); + o.Content = n.CreateMap(LoadMediaType, t, c); } }, { - "links", (o, n, t) => + "links", (o, n, t, c) => { - o.Links = n.CreateMap(LoadLink, t); + o.Links = n.CreateMap(LoadLink, t, c); } } }; @@ -45,24 +46,24 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _responsePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiResponse LoadResponse(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiResponse LoadResponse(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("response"); + var JsonObject = node.CheckMapNode("response", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var responseReference = new OpenApiResponseReference(reference.Item1, hostDocument, reference.Item2); - responseReference.Reference.SetMetadataFromMapNode(mapNode); + responseReference.Reference.SetMetadataFromJsonObject(JsonObject); return responseReference; } var response = new OpenApiResponse(); - ParseMap(mapNode, response, _responseFixedFields, _responsePatternFields, hostDocument); + ParseMap(JsonObject, response, _responseFixedFields, _responsePatternFields, hostDocument, context); return response; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiResponsesDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiResponsesDeserializer.cs index 972000b0a..ae928dc99 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiResponsesDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiResponsesDeserializer.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V32 @@ -15,17 +17,17 @@ internal static partial class OpenApiV32Deserializer public static readonly PatternFieldMap ResponsesPatternFields = new() { - {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t) => o.Add(p, LoadResponse(n, t))}, - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => !s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, t, c) => o.Add(p, LoadResponse(n, t, c))}, + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiResponses LoadResponses(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiResponses LoadResponses(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("Responses"); + var JsonObject = node.CheckMapNode("Responses", context); var domainObject = new OpenApiResponses(); - ParseMap(mapNode, domainObject, ResponsesFixedFields, ResponsesPatternFields, hostDocument); + ParseMap(JsonObject, domainObject, ResponsesFixedFields, ResponsesPatternFields, hostDocument, context); return domainObject; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiSchemaDeserializer.cs index c18c48462..45899e45e 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiSchemaDeserializer.cs @@ -14,39 +14,39 @@ internal static partial class OpenApiV32Deserializer { { "title", - (o, n, _) => o.Title = n.GetScalarValue() + (o, n, _, c) => o.Title = n.GetScalarValue() }, { "$schema", - (o, n, _) => { if (n.GetScalarValue() is string {} sSchema && Uri.TryCreate(sSchema, UriKind.Absolute, out var schema)) {o.Schema = schema;}} + (o, n, _, c) => { if (n.GetScalarValue() is string {} sSchema && Uri.TryCreate(sSchema, UriKind.Absolute, out var schema)) {o.Schema = schema;}} }, { "$id", - (o, n, _) => o.Id = n.GetScalarValue() + (o, n, _, c) => o.Id = n.GetScalarValue() }, { "$comment", - (o, n, _) => o.Comment = n.GetScalarValue() + (o, n, _, c) => o.Comment = n.GetScalarValue() }, { "$vocabulary", - (o, n, _) => o.Vocabulary = n.CreateSimpleMap(LoadBool).ToDictionary(kvp => kvp.Key, kvp => kvp.Value ?? false) + (o, n, _, c) => o.Vocabulary = n.CreateSimpleMap(LoadBool, c).ToDictionary(kvp => kvp.Key, kvp => kvp.Value ?? false) }, { "$dynamicRef", - (o, n, _) => o.DynamicRef = n.GetScalarValue() + (o, n, _, c) => o.DynamicRef = n.GetScalarValue() }, { "$dynamicAnchor", - (o, n, _) => o.DynamicAnchor = n.GetScalarValue() + (o, n, _, c) => o.DynamicAnchor = n.GetScalarValue() }, { "$defs", - (o, n, t) => o.Definitions = n.CreateMap(LoadSchema, t) + (o, n, t, c) => o.Definitions = n.CreateMap(LoadSchema, t, c) }, { "multipleOf", - (o, n, _) => + (o, n, _, c) => { var multipleOf = n.GetScalarValue(); if (multipleOf != null) @@ -57,7 +57,7 @@ internal static partial class OpenApiV32Deserializer }, { "maximum", - (o, n,_) => + (o, n, _, c) => { var max = n.GetScalarValue(); if (!string.IsNullOrEmpty(max)) @@ -68,11 +68,11 @@ internal static partial class OpenApiV32Deserializer }, { "exclusiveMaximum", - (o, n, _) => o.ExclusiveMaximum = n.GetScalarValue() + (o, n, _, c) => o.ExclusiveMaximum = n.GetScalarValue() }, { "minimum", - (o, n, _) => + (o, n, _, c) => { var min = n.GetScalarValue(); if (!string.IsNullOrEmpty(min)) @@ -83,11 +83,11 @@ internal static partial class OpenApiV32Deserializer }, { "exclusiveMinimum", - (o, n, _) => o.ExclusiveMinimum = n.GetScalarValue() + (o, n, _, c) => o.ExclusiveMinimum = n.GetScalarValue() }, { "maxLength", - (o, n, _) => + (o, n, _, c) => { var maxLength = n.GetScalarValue(); if (maxLength != null) @@ -98,7 +98,7 @@ internal static partial class OpenApiV32Deserializer }, { "minLength", - (o, n, _) => + (o, n, _, c) => { var minLength = n.GetScalarValue(); if (minLength != null) @@ -109,11 +109,11 @@ internal static partial class OpenApiV32Deserializer }, { "pattern", - (o, n, _) => o.Pattern = n.GetScalarValue() + (o, n, _, c) => o.Pattern = n.GetScalarValue() }, { "maxItems", - (o, n, _) => + (o, n, _, c) => { var maxItems = n.GetScalarValue(); if (maxItems != null) @@ -124,7 +124,7 @@ internal static partial class OpenApiV32Deserializer }, { "minItems", - (o, n, _) => + (o, n, _, c) => { var minItems = n.GetScalarValue(); if (minItems != null) @@ -135,7 +135,7 @@ internal static partial class OpenApiV32Deserializer }, { "uniqueItems", - (o, n, _) => + (o, n, _, c) => { var uniqueItems = n.GetScalarValue(); if (uniqueItems != null) @@ -146,10 +146,10 @@ internal static partial class OpenApiV32Deserializer }, { "unevaluatedProperties", - (o, n, t) => + (o, n, t, c) => { // Handle both boolean (false/true) and schema object cases - if (n is ValueNode) + if (n is JsonValue) { var value = n.GetScalarValue(); if (value is not null) @@ -160,13 +160,13 @@ internal static partial class OpenApiV32Deserializer else { // Schema object case: deserialize as schema - o.UnevaluatedPropertiesSchema = LoadSchema(n, t); + o.UnevaluatedPropertiesSchema = LoadSchema(n, t, c); } } }, { "maxProperties", - (o, n, _) => + (o, n, _, c) => { var maxProps = n.GetScalarValue(); if (maxProps != null) @@ -177,7 +177,7 @@ internal static partial class OpenApiV32Deserializer }, { "minProperties", - (o, n, _) => + (o, n, _, c) => { var minProps = n.GetScalarValue(); if (minProps != null) @@ -188,23 +188,23 @@ internal static partial class OpenApiV32Deserializer }, { "required", - (o, n, doc) => o.Required = new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc).Where(s => s != null)) + (o, n, doc, c) => o.Required = new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc, c).OfType()) }, { "enum", - (o, n, _) => o.Enum = n.CreateListOfAny() + (o, n, _, c) => o.Enum = n.CreateListOfAny(c) }, { "type", - (o, n, doc) => + (o, n, doc, c) => { - if (n is ValueNode) + if (n is JsonValue) { o.Type = n.GetScalarValue()?.ToJsonSchemaType(); } else { - var list = n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc); + var list = n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc, c); JsonSchemaType combinedType = 0; foreach(var type in list.Where(static t => t is not null).Select(static t => t!.ToJsonSchemaType())) { @@ -216,40 +216,40 @@ internal static partial class OpenApiV32Deserializer }, { "const", - (o, n, _) => o.Const = n.GetScalarValue() + (o, n, _, c) => o.Const = n.GetScalarValue() }, { "allOf", - (o, n, t) => o.AllOf = n.CreateList(LoadSchema, t) + (o, n, t, c) => o.AllOf = n.CreateList(LoadSchema, t, c) }, { "oneOf", - (o, n, t) => o.OneOf = n.CreateList(LoadSchema, t) + (o, n, t, c) => o.OneOf = n.CreateList(LoadSchema, t, c) }, { "anyOf", - (o, n, t) => o.AnyOf = n.CreateList(LoadSchema, t) + (o, n, t, c) => o.AnyOf = n.CreateList(LoadSchema, t, c) }, { "not", - (o, n, doc) => o.Not = LoadSchema(n, doc) + (o, n, doc, c) => o.Not = LoadSchema(n, doc, c) }, { "items", - (o, n, doc) => o.Items = LoadSchema(n, doc) + (o, n, doc, c) => o.Items = LoadSchema(n, doc, c) }, { "properties", - (o, n, t) => o.Properties = n.CreateMap(LoadSchema, t) + (o, n, t, c) => o.Properties = n.CreateMap(LoadSchema, t, c) }, { "patternProperties", - (o, n, t) => o.PatternProperties = n.CreateMap(LoadSchema, t) + (o, n, t, c) => o.PatternProperties = n.CreateMap(LoadSchema, t, c) }, { - "additionalProperties", (o, n, doc) => + "additionalProperties", (o, n, doc, c) => { - if (n is ValueNode) + if (n is JsonValue) { var value = n.GetScalarValue(); if (value is not null) @@ -259,25 +259,25 @@ internal static partial class OpenApiV32Deserializer } else { - o.AdditionalProperties = LoadSchema(n, doc); + o.AdditionalProperties = LoadSchema(n, doc, c); } } }, { "description", - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _, c) => o.Description = n.GetScalarValue() }, { "format", - (o, n, _) => o.Format = n.GetScalarValue() + (o, n, _, c) => o.Format = n.GetScalarValue() }, { "default", - (o, n, _) => o.Default = n.CreateAny() + (o, n, _, c) => o.Default = n.CreateAny() }, { "nullable", - (o, n, _) => + (o, n, _, c) => { var value = n.GetScalarValue(); if (value is not null) @@ -295,11 +295,11 @@ internal static partial class OpenApiV32Deserializer }, { "discriminator", - (o, n, doc) => o.Discriminator = LoadDiscriminator(n, doc) + (o, n, doc, c) => o.Discriminator = LoadDiscriminator(n, doc, c) }, { "readOnly", - (o, n, _) => + (o, n, _, c) => { var readOnly = n.GetScalarValue(); if (readOnly != null) @@ -310,7 +310,7 @@ internal static partial class OpenApiV32Deserializer }, { "writeOnly", - (o, n, _) => + (o, n, _, c) => { var writeOnly = n.GetScalarValue(); if (writeOnly != null) @@ -321,23 +321,23 @@ internal static partial class OpenApiV32Deserializer }, { "xml", - (o, n, doc) => o.Xml = LoadXml(n, doc) + (o, n, doc, c) => o.Xml = LoadXml(n, doc, c) }, { "externalDocs", - (o, n, doc) => o.ExternalDocs = LoadExternalDocs(n, doc) + (o, n, doc, c) => o.ExternalDocs = LoadExternalDocs(n, doc, c) }, { "example", - (o, n, _) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n.CreateAny() }, { "examples", - (o, n, _) => o.Examples = n.CreateListOfAny() + (o, n, _, c) => o.Examples = n.CreateListOfAny(c) }, { "deprecated", - (o, n, t) => + (o, n, t, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -348,22 +348,22 @@ internal static partial class OpenApiV32Deserializer }, { "dependentRequired", - (o, n, doc) => + (o, n, doc, c) => { - o.DependentRequired = n.CreateArrayMap((n2, p) => n2.GetScalarValue(), doc); + o.DependentRequired = n.CreateArrayMap((n2, p) => n2.GetScalarValue()!, doc, c); } }, }; private static readonly PatternFieldMap _openApiSchemaPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiSchema LoadSchema(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiSchema LoadSchema(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { // Handle boolean schemas (true/false) for JSON Schema 2020-12 compatibility - if (node is ValueNode valueNode && valueNode.TryGetValue(out var boolValue)) + if (node is JsonValue jsonValue && jsonValue.TryGetValue(out var boolValue)) { var boolSchema = new OpenApiSchema(); if (!boolValue) @@ -375,38 +375,29 @@ public static IOpenApiSchema LoadSchema(ParseNode node, OpenApiDocument hostDocu return boolSchema; } - var mapNode = node.CheckMapNode(OpenApiConstants.Schema); + var JsonObject = node.CheckMapNode(OpenApiConstants.Schema, context); - var pointer = mapNode.GetReferencePointer(); - var identifier = mapNode.GetJsonSchemaIdentifier(); + var pointer = JsonObject.GetReferencePointer(); + var identifier = JsonObject.GetJsonSchemaIdentifier(); if (pointer != null) { - var nodeLocation = node.Context.GetLocation(); + var nodeLocation = context.GetLocation(); var reference = GetReferenceIdAndExternalResource(pointer); var result = new OpenApiSchemaReference(reference.Item1, hostDocument, reference.Item2); - result.Reference.SetMetadataFromMapNode(mapNode); + result.Reference.SetMetadataFromJsonObject(JsonObject); result.Reference.SetJsonPointerPath(pointer, nodeLocation); return result; } var schema = new OpenApiSchema(); - foreach (var propertyNode in mapNode) - { - bool isRecognized = _openApiSchemaFixedFields.ContainsKey(propertyNode.Name) || - _openApiSchemaPatternFields.Any(p => p.Key(propertyNode.Name)); - - if (isRecognized) - { - propertyNode.ParseField(schema, _openApiSchemaFixedFields, _openApiSchemaPatternFields, hostDocument); - } - else if (propertyNode.JsonNode is not null) + JsonObject.ParseMap(schema, _openApiSchemaFixedFields, _openApiSchemaPatternFields, hostDocument, context, + static (schema, name, value) => { schema.UnrecognizedKeywords ??= new Dictionary(StringComparer.Ordinal); - schema.UnrecognizedKeywords[propertyNode.Name] = propertyNode.JsonNode; - } - } + schema.UnrecognizedKeywords[name] = value; + }); if (schema.Extensions is not null && schema.Extensions.ContainsKey(OpenApiConstants.NullableExtension)) { @@ -427,4 +418,3 @@ public static IOpenApiSchema LoadSchema(ParseNode node, OpenApiDocument hostDocu return schema; } } - diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiSecurityRequirementDeserializer.cs index a2f1326a4..2410e2920 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiSecurityRequirementDeserializer.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System.Linq; namespace Microsoft.OpenApi.Reader.V32 @@ -11,17 +13,17 @@ namespace Microsoft.OpenApi.Reader.V32 /// internal static partial class OpenApiV32Deserializer { - public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiSecurityRequirement LoadSecurityRequirement(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("security"); + var JsonObject = node.CheckMapNode("security", context); var securityRequirement = new OpenApiSecurityRequirement(); - foreach (var property in mapNode) + foreach (var property in JsonObject) { - var scheme = LoadSecuritySchemeByReference(property.Name, hostDocument); + var scheme = LoadSecuritySchemeByReference(property.Key, hostDocument); - var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue(), hostDocument) + var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue(), hostDocument, context) .OfType() .ToList(); if (scheme != null) @@ -30,8 +32,8 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, } else { - mapNode.Context.Diagnostic.Errors.Add( - new OpenApiError(node.Context.GetLocation(), $"Scheme {property.Name} is not found")); + context.Diagnostic.Errors.Add( + new OpenApiError(context.GetLocation(), $"Scheme {property.Key} is not found")); } } @@ -44,4 +46,3 @@ private static OpenApiSecuritySchemeReference LoadSecuritySchemeByReference(stri } } } - diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiSecuritySchemeDeserializer.cs index f0acc7ea6..948bdc7df 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiSecuritySchemeDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V32 @@ -15,9 +17,9 @@ internal static partial class OpenApiV32Deserializer new() { { - "type", (o, n, _) => + "type", (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var type)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var type)) { return; } @@ -25,21 +27,21 @@ internal static partial class OpenApiV32Deserializer } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - "name", (o, n, _) => + "name", (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { - "in", (o, n, _) => + "in", (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var _in)) { return; } @@ -47,19 +49,19 @@ internal static partial class OpenApiV32Deserializer } }, { - "scheme", (o, n, _) => + "scheme", (o, n, _, c) => { o.Scheme = n.GetScalarValue(); } }, { - "bearerFormat", (o, n, _) => + "bearerFormat", (o, n, _, c) => { o.BearerFormat = n.GetScalarValue(); } }, { - "openIdConnectUrl", (o, n, _) => + "openIdConnectUrl", (o, n, _, c) => { var connectUrl = n.GetScalarValue(); if (connectUrl != null) @@ -69,7 +71,7 @@ internal static partial class OpenApiV32Deserializer } }, { - "oauth2MetadataUrl", (o, n, _) => + "oauth2MetadataUrl", (o, n, _, c) => { var metadataUrl = n.GetScalarValue(); if (metadataUrl != null) @@ -79,13 +81,13 @@ internal static partial class OpenApiV32Deserializer } }, { - "flows", (o, n, t) => + "flows", (o, n, t, c) => { - o.Flows = LoadOAuthFlows(n, t); + o.Flows = LoadOAuthFlows(n, t, c); } }, { - "deprecated", (o, n, _) => + "deprecated", (o, n, _, c) => { var deprecated = n.GetScalarValue(); if (deprecated != null) @@ -99,27 +101,24 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _securitySchemePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static IOpenApiSecurityScheme LoadSecurityScheme(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiSecurityScheme LoadSecurityScheme(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("securityScheme"); + var JsonObject = node.CheckMapNode("securityScheme", context); - var pointer = mapNode.GetReferencePointer(); + var pointer = JsonObject.GetReferencePointer(); if (pointer != null) { var reference = GetReferenceIdAndExternalResource(pointer); var securitySchemeReference = new OpenApiSecuritySchemeReference(reference.Item1, hostDocument, reference.Item2); - securitySchemeReference.Reference.SetMetadataFromMapNode(mapNode); + securitySchemeReference.Reference.SetMetadataFromJsonObject(JsonObject); return securitySchemeReference; } var securityScheme = new OpenApiSecurityScheme(); - foreach (var property in mapNode) - { - property.ParseField(securityScheme, _securitySchemeFixedFields, _securitySchemePatternFields, hostDocument); - } + ParseMap(JsonObject, securityScheme, _securitySchemeFixedFields, _securitySchemePatternFields, hostDocument, context); return securityScheme; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiServerDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiServerDeserializer.cs index 8a1e5819f..bff91580a 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiServerDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiServerDeserializer.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V32 @@ -14,43 +16,43 @@ internal static partial class OpenApiV32Deserializer private static readonly FixedFieldMap _serverFixedFields = new() { { - "url", (o, n, _) => + "url", (o, n, _, c) => { o.Url = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - "name", (o, n, _) => + "name", (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { - "variables", (o, n, t) => + "variables", (o, n, t, c) => { - o.Variables = n.CreateMap(LoadServerVariable, t); + o.Variables = n.CreateMap(LoadServerVariable, t, c); } } }; private static readonly PatternFieldMap _serverPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiServer LoadServer(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiServer LoadServer(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("server"); + var JsonObject = node.CheckMapNode("server", context); var server = new OpenApiServer(); - ParseMap(mapNode, server, _serverFixedFields, _serverPatternFields, hostDocument); + ParseMap(JsonObject, server, _serverFixedFields, _serverPatternFields, hostDocument, context); return server; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiServerVariableDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiServerVariableDeserializer.cs index 08169d474..383a2d26d 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiServerVariableDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiServerVariableDeserializer.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Linq; @@ -16,19 +18,19 @@ internal static partial class OpenApiV32Deserializer new() { { - "enum", (o, n, doc) => + "enum", (o, n, doc, c) => { - o.Enum = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc).OfType().ToList(); + o.Enum = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc, c).OfType().ToList(); } }, { - "default", (o, n, _) => + "default", (o, n, _, c) => { o.Default = n.GetScalarValue(); } }, { - "description", (o, n, _) => + "description", (o, n, _, c) => { o.Description = n.GetScalarValue(); } @@ -38,16 +40,16 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _serverVariablePatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiServerVariable LoadServerVariable(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiServerVariable LoadServerVariable(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("serverVariable"); + var JsonObject = node.CheckMapNode("serverVariable", context); var serverVariable = new OpenApiServerVariable(); - ParseMap(mapNode, serverVariable, _serverVariableFixedFields, _serverVariablePatternFields, hostDocument); + ParseMap(JsonObject, serverVariable, _serverVariableFixedFields, _serverVariablePatternFields, hostDocument, context); return serverVariable; } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiTagDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiTagDeserializer.cs index fab43129a..9ec1f7950 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiTagDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiTagDeserializer.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V32 @@ -14,31 +16,31 @@ internal static partial class OpenApiV32Deserializer private static readonly FixedFieldMap _tagFixedFields = new() { { - OpenApiConstants.Name, (o, n, _) => + OpenApiConstants.Name, (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { - OpenApiConstants.Description, (o, n, _) => + OpenApiConstants.Description, (o, n, _, c) => { o.Description = n.GetScalarValue(); } }, { - OpenApiConstants.ExternalDocs, (o, n, t) => + OpenApiConstants.ExternalDocs, (o, n, t, c) => { - o.ExternalDocs = LoadExternalDocs(n, t); + o.ExternalDocs = LoadExternalDocs(n, t, c); } }, { - OpenApiConstants.Summary, (o, n, _) => + OpenApiConstants.Summary, (o, n, _, c) => { o.Summary = n.GetScalarValue(); } }, { - "parent", (o, n, doc) => + "parent", (o, n, doc, c) => { var tagName = n.GetScalarValue(); if (tagName != null) @@ -48,7 +50,7 @@ internal static partial class OpenApiV32Deserializer } }, { - "kind", (o, n, _) => + "kind", (o, n, _, c) => { o.Kind = n.GetScalarValue(); } @@ -58,22 +60,18 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _tagPatternFields = new() { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiTag LoadTag(ParseNode n, OpenApiDocument hostDocument) + public static OpenApiTag LoadTag(JsonNode n, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = n.CheckMapNode("tag"); + var JsonObject = n.CheckMapNode("tag", context); var domainObject = new OpenApiTag(); - foreach (var propertyNode in mapNode) - { - propertyNode.ParseField(domainObject, _tagFixedFields, _tagPatternFields, hostDocument); - } + ParseMap(JsonObject, domainObject, _tagFixedFields, _tagPatternFields, hostDocument, context); return domainObject; } } } - diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiV32Deserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiV32Deserializer.cs index 55f45b38e..39c328466 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiV32Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiV32Deserializer.cs @@ -14,34 +14,27 @@ namespace Microsoft.OpenApi.Reader.V32 internal static partial class OpenApiV32Deserializer { private static void ParseMap( - MapNode? mapNode, + JsonObject? jsonObject, T domainObject, FixedFieldMap fixedFieldMap, PatternFieldMap patternFieldMap, - OpenApiDocument doc) + OpenApiDocument doc, + ParsingContext context) { - if (mapNode == null) - { - return; - } - - foreach (var propertyNode in mapNode) - { - propertyNode.ParseField(domainObject, fixedFieldMap, patternFieldMap, doc); - } - + jsonObject.ParseMap(domainObject, fixedFieldMap, patternFieldMap, doc, context); } private static void ProcessAnyFields( - MapNode mapNode, + JsonObject jsonObject, T domainObject, - AnyFieldMap anyFieldMap) + AnyFieldMap anyFieldMap, + ParsingContext context) { foreach (var anyFieldName in anyFieldMap.Keys.ToList()) { try { - mapNode.Context.StartObject(anyFieldName); + context.StartObject(anyFieldName); var any = anyFieldMap[anyFieldName].PropertyGetter(domainObject); @@ -56,32 +49,33 @@ private static void ProcessAnyFields( } catch (OpenApiException exception) { - exception.Pointer = mapNode.Context.GetLocation(); - mapNode.Context.Diagnostic.Errors.Add(new OpenApiError(exception)); + exception.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new OpenApiError(exception)); } finally { - mapNode.Context.EndObject(); + context.EndObject(); } } } private static void ProcessAnyMapFields( - MapNode mapNode, + JsonObject jsonObject, T domainObject, - AnyMapFieldMap anyMapFieldMap) + AnyMapFieldMap anyMapFieldMap, + ParsingContext context) { foreach (var anyMapFieldName in anyMapFieldMap.Keys.ToList()) { try { - mapNode.Context.StartObject(anyMapFieldName); + context.StartObject(anyMapFieldName); var propertyMapGetter = anyMapFieldMap[anyMapFieldName].PropertyMapGetter(domainObject); if (propertyMapGetter != null) { foreach (var propertyMapElement in propertyMapGetter) { - mapNode.Context.StartObject(propertyMapElement.Key); + context.StartObject(propertyMapElement.Key); if (propertyMapElement.Value != null) { @@ -96,17 +90,17 @@ private static void ProcessAnyMapFields( } catch (OpenApiException exception) { - exception.Pointer = mapNode.Context.GetLocation(); - mapNode.Context.Diagnostic.Errors.Add(new OpenApiError(exception)); + exception.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new OpenApiError(exception)); } finally { - mapNode.Context.EndObject(); + context.EndObject(); } } } - private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(ParseNode node) + private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(JsonNode node) { var value = node.GetScalarValue(); @@ -124,14 +118,14 @@ private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(Parse }; } - public static JsonNode LoadAny(ParseNode node, OpenApiDocument hostDocument) + public static JsonNode LoadAny(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { return node.CreateAny(); } - private static IOpenApiExtension LoadExtension(string name, ParseNode node) + private static IOpenApiExtension LoadExtension(string name, JsonNode node, ParsingContext context) { - if (node.Context.ExtensionParsers is not null && node.Context.ExtensionParsers.TryGetValue(name, out var parser)) + if (context.ExtensionParsers is not null && context.ExtensionParsers.TryGetValue(name, out var parser)) { try { @@ -139,20 +133,20 @@ private static IOpenApiExtension LoadExtension(string name, ParseNode node) } catch (OpenApiException ex) { - ex.Pointer = node.Context.GetLocation(); - node.Context.Diagnostic.Errors.Add(new(ex)); + ex.Pointer = context.GetLocation(); + context.Diagnostic.Errors.Add(new(ex)); } } return new JsonNodeExtension(node.CreateAny()); } - private static string? LoadString(ParseNode node) + private static string? LoadString(JsonNode node) { return node.GetScalarValue(); } - private static bool? LoadBool(ParseNode node) + private static bool? LoadBool(JsonNode node) { var value = node.GetScalarValue(); return value is not null ? bool.Parse(value) : null; @@ -180,4 +174,3 @@ private static (string, string?) GetReferenceIdAndExternalResource(string pointe } } } - diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiV32VersionService.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiV32VersionService.cs index 38e7452d1..1b736ef7f 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiV32VersionService.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiV32VersionService.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Collections.Generic; @@ -20,7 +22,7 @@ public OpenApiV32VersionService(OpenApiDiagnostic diagnostic):base(diagnostic) { } - private readonly Dictionary> _loaders = new Dictionary> + private readonly Dictionary> _loaders = new Dictionary> { [typeof(JsonNodeExtension)] = OpenApiV32Deserializer.LoadAny, [typeof(OpenApiCallback)] = OpenApiV32Deserializer.LoadCallback, @@ -54,11 +56,11 @@ public OpenApiV32VersionService(OpenApiDiagnostic diagnostic):base(diagnostic) [typeof(OpenApiSchemaReference)] = OpenApiV32Deserializer.LoadMapping }; - public override OpenApiDocument LoadDocument(RootNode rootNode, Uri location) + public override OpenApiDocument LoadDocument(JsonNode JsonNode, Uri location, ParsingContext context) { - return OpenApiV32Deserializer.LoadOpenApi(rootNode, location); + return OpenApiV32Deserializer.LoadOpenApi(JsonNode, location, context); } - internal override Dictionary> Loaders => _loaders; + internal override Dictionary> Loaders => _loaders; } } diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiXmlDeserializer.cs index 6f3de6145..593a29b78 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiXmlDeserializer.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; namespace Microsoft.OpenApi.Reader.V32 @@ -14,14 +16,14 @@ internal static partial class OpenApiV32Deserializer private static readonly FixedFieldMap _xmlFixedFields = new FixedFieldMap { { - "name", (o, n, _) => + "name", (o, n, _, c) => { o.Name = n.GetScalarValue(); } }, { "namespace", - (o, n, _) => + (o, n, _, c) => { var value = n.GetScalarValue(); if (value != null) @@ -32,13 +34,13 @@ internal static partial class OpenApiV32Deserializer }, { "prefix", - (o, n, _) => o.Prefix = n.GetScalarValue() + (o, n, _, c) => o.Prefix = n.GetScalarValue() }, { "nodeType", - (o, n, _) => + (o, n, _, c) => { - if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var nodeType)) + if (!n.GetScalarValue().TryGetEnumFromDisplayName(c, out var nodeType)) { return; } @@ -50,18 +52,15 @@ internal static partial class OpenApiV32Deserializer private static readonly PatternFieldMap _xmlPatternFields = new PatternFieldMap { - {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))} + {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; - public static OpenApiXml LoadXml(ParseNode node, OpenApiDocument hostDocument) + public static OpenApiXml LoadXml(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - var mapNode = node.CheckMapNode("xml"); + var JsonObject = node.CheckMapNode("xml", context); var xml = new OpenApiXml(); - foreach (var property in mapNode) - { - property.ParseField(xml, _xmlFixedFields, _xmlPatternFields, hostDocument); - } + ParseMap(JsonObject, xml, _xmlFixedFields, _xmlPatternFields, hostDocument, context); return xml; } diff --git a/src/Microsoft.OpenApi/Services/OpenApiFilterService.cs b/src/Microsoft.OpenApi/Services/OpenApiFilterService.cs index 101e259ce..72c529102 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiFilterService.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiFilterService.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Text.Json.Nodes; + using System; using System.Collections.Generic; using System.Diagnostics; @@ -142,26 +144,26 @@ public static OpenApiDocument CreateFilteredDocument(OpenApiDocument source, Fun /// The created . public static OpenApiUrlTreeNode CreateOpenApiUrlTreeNode(Dictionary sources) { - var rootNode = OpenApiUrlTreeNode.Create(); + var JsonNode = OpenApiUrlTreeNode.Create(); foreach (var source in sources) { - rootNode.Attach(source.Value, source.Key); + JsonNode.Attach(source.Value, source.Key); } - return rootNode; + return JsonNode; } - private static Dictionary? GetOpenApiOperations(OpenApiUrlTreeNode rootNode, string relativeUrl, string label) + private static Dictionary? GetOpenApiOperations(OpenApiUrlTreeNode JsonNode, string relativeUrl, string label) { - if (relativeUrl.Equals("/", StringComparison.Ordinal) && rootNode.HasOperations(label)) + if (relativeUrl.Equals("/", StringComparison.Ordinal) && JsonNode.HasOperations(label)) { - return rootNode.PathItems[label].Operations; + return JsonNode.PathItems[label].Operations; } var urlSegments = relativeUrl.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); Dictionary? operations = null; - var targetChild = rootNode; + var targetChild = JsonNode; /* This will help keep track of whether we've skipped a segment * in the target url due to a possible parameter naming mismatch @@ -410,14 +412,14 @@ private static Func GetRequestUrlsPr if (apiVersion is not null) { var sources = new Dictionary { { apiVersion, source } }; - var rootNode = CreateOpenApiUrlTreeNode(sources); + var JsonNode = CreateOpenApiUrlTreeNode(sources); // Iterate through urls dictionary and fetch operations for each url foreach (var url in requestUrls) { var serverList = source.Servers; var path = ExtractPath(url.Key, serverList); - var openApiOperations = GetOpenApiOperations(rootNode, path, apiVersion); + var openApiOperations = GetOpenApiOperations(JsonNode, path, apiVersion); if (openApiOperations == null) { Debug.WriteLine($"The url {url.Key} could not be found in the OpenApi description"); diff --git a/test/Microsoft.OpenApi.Readers.Tests/ParseNodeTests.cs b/test/Microsoft.OpenApi.Readers.Tests/ParseNodeTests.cs index 66379cb91..9d7ecd68f 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/ParseNodeTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/ParseNodeTests.cs @@ -6,7 +6,7 @@ namespace Microsoft.OpenApi.Tests { - public class ParseNodeTests + public class JsonNodeParsingTests { [Fact] public void BrokenSimpleList() @@ -58,4 +58,3 @@ public void BadSchema() } } } - diff --git a/test/Microsoft.OpenApi.Readers.Tests/TestHelper.cs b/test/Microsoft.OpenApi.Readers.Tests/TestHelper.cs index 9623bf761..7173d9836 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/TestHelper.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/TestHelper.cs @@ -1,7 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.IO; +using System.Text.Json.Nodes; using Microsoft.OpenApi.Reader; using Microsoft.OpenApi.YamlReader; using SharpYaml.Serialization; @@ -10,16 +11,15 @@ namespace Microsoft.OpenApi.Readers.Tests { internal class TestHelper { - public static MapNode CreateYamlMapNode(Stream stream) + public static JsonNode CreateYamlJsonNode(Stream stream) { var yamlStream = new YamlStream(); yamlStream.Load(new StreamReader(stream)); var yamlNode = yamlStream.Documents[0].RootNode; - var context = new ParsingContext(new OpenApiDiagnostic()); var asJsonNode = yamlNode.ToJsonNode(); - return new MapNode(context, asJsonNode); + return asJsonNode; } } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiHeaderTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiHeaderTests.cs index b70b9669f..e27c8e7ed 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiHeaderTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiHeaderTests.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +using System.Text.Json.Nodes; +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.IO; @@ -19,14 +20,14 @@ public class OpenApiHeaderTests public void ParseHeaderWithDefaultShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithDefault.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var header = OpenApiV2Deserializer.LoadHeader(node, new()); + var header = OpenApiV2Deserializer.LoadHeader(node, new(), new ParsingContext(new())); // Assert header.Should().BeEquivalentTo( @@ -48,14 +49,14 @@ public void ParseHeaderWithDefaultShouldSucceed() public void ParseHeaderWithEnumShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "headerWithEnum.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var header = OpenApiV2Deserializer.LoadHeader(node, new()); + var header = OpenApiV2Deserializer.LoadHeader(node, new(), new ParsingContext(new())); // Assert header.Should().BeEquivalentTo( diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiOperationTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiOperationTests.cs index 5160f308f..92d50c42e 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiOperationTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiOperationTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.Collections.Generic; @@ -120,14 +120,14 @@ public class OpenApiOperationTests public void ParseBasicOperationShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicOperation.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var operation = OpenApiV2Deserializer.LoadOperation(node, new()); + var operation = OpenApiV2Deserializer.LoadOperation(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent(_basicOperation, operation); @@ -137,15 +137,15 @@ public void ParseBasicOperationShouldSucceed() public async Task ParseBasicOperationTwiceShouldYieldSameObject() { // Arrange - MapNode node; + JsonNode node; using (var stream = new MemoryStream( Encoding.Default.GetBytes(await _basicOperation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0)))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var operation = OpenApiV2Deserializer.LoadOperation(node, new()); + var operation = OpenApiV2Deserializer.LoadOperation(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent(_basicOperation, operation); @@ -155,14 +155,14 @@ public async Task ParseBasicOperationTwiceShouldYieldSameObject() public void ParseOperationWithBodyShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "operationWithBody.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var operation = OpenApiV2Deserializer.LoadOperation(node, new()); + var operation = OpenApiV2Deserializer.LoadOperation(node, new(), new ParsingContext(new())); // Assert operation.Should().BeEquivalentTo(_operationWithBody, options => options.IgnoringCyclicReferences()); @@ -172,15 +172,15 @@ public void ParseOperationWithBodyShouldSucceed() public async Task ParseOperationWithBodyTwiceShouldYieldSameObject() { // Arrange - MapNode node; + JsonNode node; using (var stream = new MemoryStream( Encoding.Default.GetBytes(await _operationWithBody.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0)))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var operation = OpenApiV2Deserializer.LoadOperation(node, new()); + var operation = OpenApiV2Deserializer.LoadOperation(node, new(), new ParsingContext(new())); // Assert operation.Should().BeEquivalentTo(_operationWithBody, options => options.IgnoringCyclicReferences()); @@ -190,14 +190,14 @@ public async Task ParseOperationWithBodyTwiceShouldYieldSameObject() public void ParseOperationWithResponseExamplesShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "operationWithResponseExamples.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var operation = OpenApiV2Deserializer.LoadOperation(node, new()); + var operation = OpenApiV2Deserializer.LoadOperation(node, new(), new ParsingContext(new())); // Assert operation.Should().BeEquivalentTo( @@ -256,12 +256,12 @@ public void ParseOperationWithResponseExamplesShouldSucceed() public void ParseOperationWithEmptyProducesArraySetsResponseSchemaIfExists() { // Arrange - MapNode node; + JsonNode node; using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "operationWithEmptyProducesArrayInResponse.json")); - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); // Act - var operation = OpenApiV2Deserializer.LoadOperation(node, new()); + var operation = OpenApiV2Deserializer.LoadOperation(node, new(), new ParsingContext(new())); var expected = @"{ ""produces"": [ ""application/octet-stream"" @@ -292,12 +292,12 @@ public void ParseOperationWithEmptyProducesArraySetsResponseSchemaIfExists() public void ParseOperationWithBodyAndEmptyConsumesSetsRequestBodySchemaIfExists() { // Arrange - MapNode node; + JsonNode node; using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "operationWithBodyAndEmptyConsumes.yaml")); - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); // Act - var operation = OpenApiV2Deserializer.LoadOperation(node, new()); + var operation = OpenApiV2Deserializer.LoadOperation(node, new(), new ParsingContext(new())); // Assert operation.Should().BeEquivalentTo(_operationWithBody, options => options.IgnoringCyclicReferences()); @@ -307,14 +307,14 @@ public void ParseOperationWithBodyAndEmptyConsumesSetsRequestBodySchemaIfExists( public async Task ParseV2ResponseWithExamplesExtensionWorks() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "opWithResponseExamplesExtension.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var operation = OpenApiV2Deserializer.LoadOperation(node, new()); + var operation = OpenApiV2Deserializer.LoadOperation(node, new(), new ParsingContext(new())); var actual = await operation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); // Assert @@ -357,14 +357,14 @@ public async Task ParseV2ResponseWithExamplesExtensionWorks() public async Task LoadV3ExamplesInResponseAsExtensionsWorks() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "v3OperationWithResponseExamples.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var operation = OpenApiV3Deserializer.LoadOperation(node, new()); + var operation = OpenApiV3Deserializer.LoadOperation(node, new(), new ParsingContext(new())); var actual = await operation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); // Assert @@ -407,14 +407,14 @@ public async Task LoadV3ExamplesInResponseAsExtensionsWorks() public async Task LoadV2OperationWithBodyParameterExamplesWorks() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "opWithBodyParameterExamples.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var operation = OpenApiV2Deserializer.LoadOperation(node, new()); + var operation = OpenApiV2Deserializer.LoadOperation(node, new(), new ParsingContext(new())); var actual = await operation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_0); // Assert @@ -458,14 +458,14 @@ public async Task LoadV2OperationWithBodyParameterExamplesWorks() public async Task LoadV3ExamplesInRequestBodyParameterAsExtensionsWorks() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "v3OperationWithBodyParameterExamples.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var operation = OpenApiV3Deserializer.LoadOperation(node, new()); + var operation = OpenApiV3Deserializer.LoadOperation(node, new(), new ParsingContext(new())); var actual = await operation.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi2_0); // Assert diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiParameterTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiParameterTests.cs index 973f4bb8e..43eefc5c0 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiParameterTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiParameterTests.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +using System.Text.Json.Nodes; +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.IO; @@ -20,14 +21,14 @@ public class OpenApiParameterTests public void ParseBodyParameterShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "bodyParameter.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var parameter = OpenApiV2Deserializer.LoadParameter(node, new()); + var parameter = OpenApiV2Deserializer.LoadParameter(node, new(), new ParsingContext(new())); // Assert // Body parameter is currently not translated via LoadParameter. @@ -39,14 +40,14 @@ public void ParseBodyParameterShouldSucceed() public void ParsePathParameterShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "pathParameter.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var parameter = OpenApiV2Deserializer.LoadParameter(node, new()); + var parameter = OpenApiV2Deserializer.LoadParameter(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( @@ -68,14 +69,14 @@ public void ParsePathParameterShouldSucceed() public void ParseQueryParameterShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "queryParameter.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var parameter = OpenApiV2Deserializer.LoadParameter(node, new()); + var parameter = OpenApiV2Deserializer.LoadParameter(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( @@ -103,14 +104,14 @@ public void ParseQueryParameterShouldSucceed() public void ParseParameterWithNullLocationShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithNullLocation.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var parameter = OpenApiV2Deserializer.LoadParameter(node, new()); + var parameter = OpenApiV2Deserializer.LoadParameter(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( @@ -132,14 +133,14 @@ public void ParseParameterWithNullLocationShouldSucceed() public void ParseParameterWithNoLocationShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithNoLocation.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var parameter = OpenApiV2Deserializer.LoadParameter(node, new()); + var parameter = OpenApiV2Deserializer.LoadParameter(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( @@ -161,14 +162,14 @@ public void ParseParameterWithNoLocationShouldSucceed() public void ParseParameterWithNoSchemaShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithNoSchema.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var parameter = OpenApiV2Deserializer.LoadParameter(node, new()); + var parameter = OpenApiV2Deserializer.LoadParameter(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( @@ -186,14 +187,14 @@ public void ParseParameterWithNoSchemaShouldSucceed() public void ParseParameterWithUnknownLocationShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithUnknownLocation.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var parameter = OpenApiV2Deserializer.LoadParameter(node, new()); + var parameter = OpenApiV2Deserializer.LoadParameter(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( @@ -215,14 +216,14 @@ public void ParseParameterWithUnknownLocationShouldSucceed() public void ParseParameterWithDefaultShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithDefault.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var parameter = OpenApiV2Deserializer.LoadParameter(node, new()); + var parameter = OpenApiV2Deserializer.LoadParameter(node, new(), new ParsingContext(new())); // Assert parameter.Should().BeEquivalentTo( @@ -245,14 +246,14 @@ public void ParseParameterWithDefaultShouldSucceed() public void ParseParameterWithEnumShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithEnum.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var parameter = OpenApiV2Deserializer.LoadParameter(node, new()); + var parameter = OpenApiV2Deserializer.LoadParameter(node, new(), new ParsingContext(new())); var expected = new OpenApiParameter { In = ParameterLocation.Path, @@ -288,14 +289,14 @@ public void ParseFormDataParameterShouldSucceed() ""description"": ""file to upload"", ""format"": ""binary"" }"; - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "formDataParameter.json"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var operation = OpenApiV2Deserializer.LoadOperation(node, new()); + var operation = OpenApiV2Deserializer.LoadOperation(node, new(), new ParsingContext(new())); var schema = operation.RequestBody?.Content["multipart/form-data"].Schema.Properties["file"]; var writer = new StringWriter(); schema.SerializeAsV2(new OpenApiJsonWriter(writer)); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs index cb41e36b2..e8b340bbb 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiPathItemTests.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +using System.Text.Json.Nodes; +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; @@ -250,10 +251,10 @@ public void ParseBasicPathItemWithFormDataShouldSucceed() { // Arrange using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicPathItemWithFormData.yaml")); - var node = TestHelper.CreateYamlMapNode(stream); + var node = TestHelper.CreateYamlJsonNode(stream); // Act - var pathItem = OpenApiV2Deserializer.LoadPathItem(node, new()); + var pathItem = OpenApiV2Deserializer.LoadPathItem(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent(_basicPathItemWithFormData, pathItem); @@ -263,14 +264,14 @@ public void ParseBasicPathItemWithFormDataShouldSucceed() public void ParsePathItemWithFormDataPathParameterShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "pathItemWithFormDataPathParameter.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var pathItem = OpenApiV2Deserializer.LoadPathItem(node, new()); + var pathItem = OpenApiV2Deserializer.LoadPathItem(node, new(), new ParsingContext(new())); // Assert // FormData parameters at in the path level are pushed into Operation request bodies. @@ -282,14 +283,14 @@ public void ParsePathItemWithFormDataPathParameterShouldSucceed() public void ParsePathItemBodyDataPathParameterShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "pathItemWithBodyPathParameter.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var pathItem = OpenApiV2Deserializer.LoadPathItem(node, new()); + var pathItem = OpenApiV2Deserializer.LoadPathItem(node, new(), new ParsingContext(new())); // Assert // FormData parameters at in the path level are pushed into Operation request bodies. diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSchemaTests.cs index 41f5b9f62..291e3978a 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSchemaTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.Collections.Generic; @@ -23,14 +23,14 @@ public class OpenApiSchemaTests public void ParseSchemaWithDefaultShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "schemaWithDefault.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var schema = OpenApiV2Deserializer.LoadSchema(node, new()); + var schema = OpenApiV2Deserializer.LoadSchema(node, new(), new ParsingContext(new())); // Assert schema.Should().BeEquivalentTo(new OpenApiSchema @@ -45,14 +45,14 @@ public void ParseSchemaWithDefaultShouldSucceed() public void ParseSchemaWithExampleShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "schemaWithExample.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var schema = OpenApiV2Deserializer.LoadSchema(node, new()); + var schema = OpenApiV2Deserializer.LoadSchema(node, new(), new ParsingContext(new())); // Assert schema.Should().BeEquivalentTo( @@ -68,14 +68,14 @@ public void ParseSchemaWithExampleShouldSucceed() public void ParseSchemaWithEnumShouldSucceed() { // Arrange - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "schemaWithEnum.yaml"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var schema = OpenApiV2Deserializer.LoadSchema(node, new()); + var schema = OpenApiV2Deserializer.LoadSchema(node, new(), new ParsingContext(new())); // Assert var expected = new OpenApiSchema diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSecuritySchemeTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSecuritySchemeTests.cs index c6614adad..e108774f1 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSecuritySchemeTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiSecuritySchemeTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; @@ -28,10 +28,10 @@ public void ParseHttpSecuritySchemeShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = document.RootNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var securityScheme = OpenApiV2Deserializer.LoadSecurityScheme(node, new()); + var securityScheme = OpenApiV2Deserializer.LoadSecurityScheme(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( @@ -53,10 +53,10 @@ public void ParseApiKeySecuritySchemeShouldSucceed() var asJsonNode = document.RootNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var securityScheme = OpenApiV2Deserializer.LoadSecurityScheme(node, new()); + var securityScheme = OpenApiV2Deserializer.LoadSecurityScheme(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( @@ -78,10 +78,10 @@ public void ParseOAuth2ImplicitSecuritySchemeShouldSucceed() var asJsonNode = document.RootNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var securityScheme = OpenApiV2Deserializer.LoadSecurityScheme(node, new()); + var securityScheme = OpenApiV2Deserializer.LoadSecurityScheme(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( @@ -113,10 +113,10 @@ public void ParseOAuth2PasswordSecuritySchemeShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = document.RootNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var securityScheme = OpenApiV2Deserializer.LoadSecurityScheme(node, new()); + var securityScheme = OpenApiV2Deserializer.LoadSecurityScheme(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( @@ -148,10 +148,10 @@ public void ParseOAuth2ApplicationSecuritySchemeShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = document.RootNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var securityScheme = OpenApiV2Deserializer.LoadSecurityScheme(node, new()); + var securityScheme = OpenApiV2Deserializer.LoadSecurityScheme(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( @@ -184,10 +184,10 @@ public void ParseOAuth2AccessCodeSecuritySchemeShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = document.RootNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var securityScheme = OpenApiV2Deserializer.LoadSecurityScheme(node, new()); + var securityScheme = OpenApiV2Deserializer.LoadSecurityScheme(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiCallbackReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiCallbackReferenceDeserializerTests.cs index 5aea87294..f93b47803 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiCallbackReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiCallbackReferenceDeserializerTests.cs @@ -23,9 +23,9 @@ public void ShouldDeserializeCallbackReferenceAnnotations() // Optionally add a PathItem or similar here if needed }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadCallback(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadCallback(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiExampleReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiExampleReferenceDeserializerTests.cs index cf9f4f47c..a0563e63e 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiExampleReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiExampleReferenceDeserializerTests.cs @@ -26,9 +26,9 @@ public void ShouldDeserializeExampleReferenceAnnotations() Description = "This is an example description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadExample(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadExample(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiHeaderReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiHeaderReferenceDeserializerTests.cs index 81ef67a60..77e2dc556 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiHeaderReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiHeaderReferenceDeserializerTests.cs @@ -25,9 +25,9 @@ public void ShouldDeserializeReferenceAnnotations() Description = "This is a header" }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadHeader(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadHeader(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiInfoTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiInfoTests.cs index 4d6bf076f..1af2aca13 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiInfoTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiInfoTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using Microsoft.OpenApi.Reader; using Microsoft.OpenApi.Reader.V31; @@ -24,10 +24,10 @@ public void ParseBasicInfoShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var openApiInfo = OpenApiV31Deserializer.LoadInfo(node, new()); + var openApiInfo = OpenApiV31Deserializer.LoadInfo(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiLicenseTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiLicenseTests.cs index e8aadc9fb..26d841811 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiLicenseTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiLicenseTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.IO; @@ -27,10 +27,10 @@ public void ParseLicenseWithSpdxIdentifierShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var license = OpenApiV31Deserializer.LoadLicense(node, new()); + var license = OpenApiV31Deserializer.LoadLicense(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiLinkReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiLinkReferenceDeserializerTests.cs index e6a124a8a..c9d4a4211 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiLinkReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiLinkReferenceDeserializerTests.cs @@ -24,9 +24,9 @@ public void ShouldDeserializeLinkReferenceAnnotations() Description = "This is a link description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadLink(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadLink(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiMediaTypeTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiMediaTypeTests.cs index c03ad6196..39ea5420d 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiMediaTypeTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiMediaTypeTests.cs @@ -1,3 +1,4 @@ +using System.Text.Json.Nodes; // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. @@ -101,14 +102,14 @@ public async Task ParseMediaTypeWithEmptyArrayInExamplesWorks() } } "; - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "examplesWithEmptyArray.json"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var mediaType = OpenApiV31Deserializer.LoadMediaType(node, new()); + var mediaType = OpenApiV31Deserializer.LoadMediaType(node, new(), new ParsingContext(new())); var serialized = await mediaType.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_1); // Assert diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiParameterReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiParameterReferenceDeserializerTests.cs index d51274076..b98bf3aa5 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiParameterReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiParameterReferenceDeserializerTests.cs @@ -26,9 +26,9 @@ public void ShouldDeserializeParameterReferenceAnnotations() Description = "This is a parameter description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadParameter(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadParameter(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiPathItemReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiPathItemReferenceDeserializerTests.cs index ac7d62d3a..07cbdbcbc 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiPathItemReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiPathItemReferenceDeserializerTests.cs @@ -26,9 +26,9 @@ public void ShouldDeserializePathItemReferenceAnnotations() Description = "This is a path item description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadPathItem(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadPathItem(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiRequestBodyReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiRequestBodyReferenceDeserializerTests.cs index 04ecdc72e..a98a857ab 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiRequestBodyReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiRequestBodyReferenceDeserializerTests.cs @@ -24,9 +24,9 @@ public void ShouldDeserializeRequestBodyReferenceAnnotations() Description = "This is a request body description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadRequestBody(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadRequestBody(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiResponseReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiResponseReferenceDeserializerTests.cs index 6ca61c7c4..dbe9848f8 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiResponseReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiResponseReferenceDeserializerTests.cs @@ -24,9 +24,9 @@ public void ShouldDeserializeResponseReferenceAnnotations() Description = "This is a response description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadResponse(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadResponse(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaReferenceDeserializerTests.cs index 13e89df71..782ae6e45 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaReferenceDeserializerTests.cs @@ -38,9 +38,9 @@ public void ShouldDeserializeSchemaReferenceAnnotations() Examples = new List { "example value" }, }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadSchema(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadSchema(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSecuritySchemeReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSecuritySchemeReferenceDeserializerTests.cs index 7084a1d56..7767148a5 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSecuritySchemeReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSecuritySchemeReferenceDeserializerTests.cs @@ -27,9 +27,9 @@ public void ShouldDeserializeSecuritySchemeReferenceAnnotations() Description = "This is a security scheme description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadSecurityScheme(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadSecurityScheme(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); @@ -55,9 +55,9 @@ public void ShouldDeserializeSecuritySchemeWithXOaiDeprecatedExtension() var hostDocument = new OpenApiDocument(); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadSecurityScheme(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadSecurityScheme(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultScheme = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiServerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiServerTests.cs index 07553cfb1..da5dbf0a7 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiServerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiServerTests.cs @@ -27,10 +27,10 @@ public void ParseServerWithXOaiNameExtensionShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var openApiServer = OpenApiV31Deserializer.LoadServer(node, new()); + var openApiServer = OpenApiV31Deserializer.LoadServer(node, new(), new ParsingContext(new())); // Assert Assert.Equal("https://dev.example.com", openApiServer.Url); @@ -58,10 +58,10 @@ public void ParseServerWithOtherExtensionShouldKeepExtension() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var openApiServer = OpenApiV31Deserializer.LoadServer(node, new()); + var openApiServer = OpenApiV31Deserializer.LoadServer(node, new(), new ParsingContext(new())); // Assert Assert.Equal("https://example.com", openApiServer.Url); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiTagDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiTagDeserializerTests.cs index 1a4d432f3..209d4a9e1 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiTagDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiTagDeserializerTests.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Text.Json.Nodes; using Microsoft.OpenApi.Reader; using Microsoft.OpenApi.Reader.V31; @@ -36,9 +36,9 @@ public void ShouldDeserializeTagWithNewV31Properties() }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadTag(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadTag(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); Assert.Equal("store", result.Name); @@ -69,9 +69,9 @@ public void ShouldDeserializeTagWithBasicProperties() var hostDocument = new OpenApiDocument(); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadTag(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadTag(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); Assert.Equal("pets", result.Name); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiTagReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiTagReferenceDeserializerTests.cs index 8bbac7fd5..1ccd32312 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiTagReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiTagReferenceDeserializerTests.cs @@ -29,9 +29,9 @@ public void ShouldDeserializeTagReferenceAnnotations() Description = "This is a tag description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV31Deserializer.LoadOperation(parseNode, hostDocument); + var result = OpenApiV31Deserializer.LoadOperation(parseNode, hostDocument, new ParsingContext(new())); // this diverges from the other unit tests because Tag References are implemented // through the reference infrastructure for convenience, but the behave quite differently diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiCallbackReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiCallbackReferenceDeserializerTests.cs index d73bfbd2c..453827dff 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiCallbackReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiCallbackReferenceDeserializerTests.cs @@ -23,9 +23,9 @@ public void ShouldDeserializeCallbackReferenceAnnotations() // Optionally add a PathItem or similar here if needed }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadCallback(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadCallback(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiExampleReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiExampleReferenceDeserializerTests.cs index c32460cba..073075ed8 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiExampleReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiExampleReferenceDeserializerTests.cs @@ -26,9 +26,9 @@ public void ShouldDeserializeExampleReferenceAnnotations() Description = "This is an example description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadExample(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadExample(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiHeaderReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiHeaderReferenceDeserializerTests.cs index abe5146c4..1c832ddcc 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiHeaderReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiHeaderReferenceDeserializerTests.cs @@ -25,9 +25,9 @@ public void ShouldDeserializeReferenceAnnotations() Description = "This is a header" }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadHeader(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadHeader(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiInfoTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiInfoTests.cs index aa578e200..6b21cac41 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiInfoTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiInfoTests.cs @@ -24,10 +24,10 @@ public void ParseBasicInfoShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var openApiInfo = OpenApiV32Deserializer.LoadInfo(node, new()); + var openApiInfo = OpenApiV32Deserializer.LoadInfo(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiLicenseTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiLicenseTests.cs index 94515b9e7..6a7f9a74e 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiLicenseTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiLicenseTests.cs @@ -27,10 +27,10 @@ public void ParseLicenseWithSpdxIdentifierShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var license = OpenApiV32Deserializer.LoadLicense(node, new()); + var license = OpenApiV32Deserializer.LoadLicense(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent( diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiLinkReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiLinkReferenceDeserializerTests.cs index 4716d05fb..7dc40aa7b 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiLinkReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiLinkReferenceDeserializerTests.cs @@ -24,9 +24,9 @@ public void ShouldDeserializeLinkReferenceAnnotations() Description = "This is a link description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadLink(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadLink(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiMediaTypeTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiMediaTypeTests.cs index 8ede04094..903ffd84c 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiMediaTypeTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiMediaTypeTests.cs @@ -1,3 +1,4 @@ +using System.Text.Json.Nodes; // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. @@ -101,14 +102,14 @@ public async Task ParseMediaTypeWithEmptyArrayInExamplesWorks() } } "; - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "examplesWithEmptyArray.json"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var mediaType = OpenApiV32Deserializer.LoadMediaType(node, new()); + var mediaType = OpenApiV32Deserializer.LoadMediaType(node, new(), new ParsingContext(new())); var serialized = await mediaType.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_2); // Assert diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiParameterReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiParameterReferenceDeserializerTests.cs index 6f4f8b4cc..5b1ea4c13 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiParameterReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiParameterReferenceDeserializerTests.cs @@ -26,9 +26,9 @@ public void ShouldDeserializeParameterReferenceAnnotations() Description = "This is a parameter description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadParameter(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadParameter(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiPathItemReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiPathItemReferenceDeserializerTests.cs index 76af3ce00..7e5916d52 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiPathItemReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiPathItemReferenceDeserializerTests.cs @@ -26,9 +26,9 @@ public void ShouldDeserializePathItemReferenceAnnotations() Description = "This is a path item description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadPathItem(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadPathItem(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiRequestBodyReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiRequestBodyReferenceDeserializerTests.cs index cda54fc9e..d1228fd65 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiRequestBodyReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiRequestBodyReferenceDeserializerTests.cs @@ -24,9 +24,9 @@ public void ShouldDeserializeRequestBodyReferenceAnnotations() Description = "This is a request body description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadRequestBody(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadRequestBody(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiResponseReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiResponseReferenceDeserializerTests.cs index eac03d63b..582159115 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiResponseReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiResponseReferenceDeserializerTests.cs @@ -24,9 +24,9 @@ public void ShouldDeserializeResponseReferenceAnnotations() Description = "This is a response description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadResponse(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadResponse(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiSchemaReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiSchemaReferenceDeserializerTests.cs index bb7b15ab0..100e72b4e 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiSchemaReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiSchemaReferenceDeserializerTests.cs @@ -38,9 +38,9 @@ public void ShouldDeserializeSchemaReferenceAnnotations() Examples = new List { "example value" }, }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadSchema(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadSchema(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiSecuritySchemeReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiSecuritySchemeReferenceDeserializerTests.cs index 166496a62..c0e533fcf 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiSecuritySchemeReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiSecuritySchemeReferenceDeserializerTests.cs @@ -27,9 +27,9 @@ public void ShouldDeserializeSecuritySchemeReferenceAnnotations() Description = "This is a security scheme description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadSecurityScheme(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadSecurityScheme(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultReference = Assert.IsType(result); @@ -55,9 +55,9 @@ public void ShouldDeserializeSecuritySchemeWithDeprecatedField() var hostDocument = new OpenApiDocument(); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadSecurityScheme(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadSecurityScheme(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); var resultScheme = Assert.IsType(result); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiServerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiServerTests.cs index c94f0e6c1..e3dda34ea 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiServerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiServerTests.cs @@ -27,10 +27,10 @@ public void ParseServerWithNameShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var openApiServer = OpenApiV32Deserializer.LoadServer(node, new()); + var openApiServer = OpenApiV32Deserializer.LoadServer(node, new(), new ParsingContext(new())); // Assert Assert.Equal("https://dev.example.com", openApiServer.Url); @@ -55,10 +55,10 @@ public void ParseServerWithoutNameShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var openApiServer = OpenApiV32Deserializer.LoadServer(node, new()); + var openApiServer = OpenApiV32Deserializer.LoadServer(node, new(), new ParsingContext(new())); // Assert Assert.Equal("https://example.com", openApiServer.Url); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiTagDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiTagDeserializerTests.cs index e3c8c4b8e..fd1c8ba33 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiTagDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiTagDeserializerTests.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Text.Json.Nodes; using Microsoft.OpenApi.Reader; using Microsoft.OpenApi.Reader.V32; @@ -36,9 +36,9 @@ public void ShouldDeserializeTagWithNewV32Properties() }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadTag(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadTag(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); Assert.Equal("store", result.Name); @@ -69,9 +69,9 @@ public void ShouldDeserializeTagWithBasicProperties() var hostDocument = new OpenApiDocument(); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadTag(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadTag(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); Assert.Equal("pets", result.Name); @@ -108,9 +108,9 @@ public void ShouldDeserializeAllNewPropertiesInV32Format() }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadTag(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadTag(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); Assert.Equal("comprehensive", result.Name); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiTagReferenceDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiTagReferenceDeserializerTests.cs index 6aa3b356a..ff3210283 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiTagReferenceDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V32Tests/OpenApiTagReferenceDeserializerTests.cs @@ -29,9 +29,9 @@ public void ShouldDeserializeTagReferenceAnnotations() Description = "This is a tag description", }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV32Deserializer.LoadOperation(parseNode, hostDocument); + var result = OpenApiV32Deserializer.LoadOperation(parseNode, hostDocument, new ParsingContext(new())); // this diverges from the other unit tests because Tag References are implemented // through the reference infrastructure for convenience, but the behave quite differently diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiMediaTypeTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiMediaTypeTests.cs index 754f11748..be0e5cc95 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiMediaTypeTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiMediaTypeTests.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +using System.Text.Json.Nodes; +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.Collections.Generic; @@ -101,14 +102,14 @@ public async Task ParseMediaTypeWithEmptyArrayInExamplesWorks() } } "; - MapNode node; + JsonNode node; using (var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "examplesWithEmptyArray.json"))) { - node = TestHelper.CreateYamlMapNode(stream); + node = TestHelper.CreateYamlJsonNode(stream); } // Act - var mediaType = OpenApiV3Deserializer.LoadMediaType(node, new()); + var mediaType = OpenApiV3Deserializer.LoadMediaType(node, new(), new ParsingContext(new())); var serialized = await mediaType.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi3_0); // Assert diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiParameterTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiParameterTests.cs index ec4af3cab..b3a58e6d0 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiParameterTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiParameterTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.Collections.Generic; @@ -354,12 +354,12 @@ public void ParseParameterWithReferenceWorks() document.Workspace.RegisterComponents(document); using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithRef.yaml")); - var node = TestHelper.CreateYamlMapNode(stream); + var node = TestHelper.CreateYamlJsonNode(stream); var expected = document.Components.Parameters["tagsParameter"]; // Act - var param = OpenApiV3Deserializer.LoadParameter(node, document); + var param = OpenApiV3Deserializer.LoadParameter(node, document, new ParsingContext(new())); // Assert Assert.Equivalent(expected, param); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSchemaTests.cs index e16e40594..943a9ca4f 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSchemaTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.Collections.Generic; @@ -34,10 +34,10 @@ public void ParsePrimitiveSchemaShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var schema = OpenApiV3Deserializer.LoadSchema(node, new()); + var schema = OpenApiV3Deserializer.LoadSchema(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent(new OpenApiDiagnostic(), diagnostic); @@ -146,10 +146,10 @@ public void ParseDictionarySchemaShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var schema = OpenApiV3Deserializer.LoadSchema(node, new()); + var schema = OpenApiV3Deserializer.LoadSchema(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent(new OpenApiDiagnostic(), diagnostic); @@ -178,10 +178,10 @@ public void ParseBasicSchemaWithExampleShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var schema = OpenApiV3Deserializer.LoadSchema(node, new()); + var schema = OpenApiV3Deserializer.LoadSchema(node, new(), new ParsingContext(new())); // Assert Assert.Equivalent(new OpenApiDiagnostic(), diagnostic); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiServerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiServerTests.cs index 468bdbd49..cdf83af47 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiServerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiServerTests.cs @@ -27,10 +27,10 @@ public void ParseServerWithXOaiNameExtensionShouldSucceed() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var openApiServer = OpenApiV3Deserializer.LoadServer(node, new()); + var openApiServer = OpenApiV3Deserializer.LoadServer(node, new(), new ParsingContext(new())); // Assert Assert.Equal("https://dev.example.com", openApiServer.Url); @@ -58,10 +58,10 @@ public void ParseServerWithOtherExtensionShouldKeepExtension() var context = new ParsingContext(diagnostic); var asJsonNode = yamlNode.ToJsonNode(); - var node = new MapNode(context, asJsonNode); + var node = asJsonNode; // Act - var openApiServer = OpenApiV3Deserializer.LoadServer(node, new()); + var openApiServer = OpenApiV3Deserializer.LoadServer(node, new(), new ParsingContext(new())); // Assert Assert.Equal("https://example.com", openApiServer.Url); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiTagDeserializerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiTagDeserializerTests.cs index bf36b25aa..4646ea658 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiTagDeserializerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiTagDeserializerTests.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Text.Json.Nodes; using Microsoft.OpenApi.Reader; using Microsoft.OpenApi.Reader.V3; @@ -36,9 +36,9 @@ public void ShouldDeserializeTagWithNewPropertiesAsExtensions() }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV3Deserializer.LoadTag(parseNode, hostDocument); + var result = OpenApiV3Deserializer.LoadTag(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); Assert.Equal("store", result.Name); @@ -81,9 +81,9 @@ public void ShouldIgnoreNativeV32PropertiesInV30() }); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV3Deserializer.LoadTag(parseNode, hostDocument); + var result = OpenApiV3Deserializer.LoadTag(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); Assert.Equal("mixed", result.Name); @@ -110,9 +110,9 @@ public void ShouldDeserializeBasicTagWithoutNewProperties() var hostDocument = new OpenApiDocument(); var jsonNode = JsonNode.Parse(json); - var parseNode = ParseNode.Create(new ParsingContext(new()), jsonNode); + var parseNode = jsonNode; - var result = OpenApiV3Deserializer.LoadTag(parseNode, hostDocument); + var result = OpenApiV3Deserializer.LoadTag(parseNode, hostDocument, new ParsingContext(new())); Assert.NotNull(result); Assert.Equal("basic", result.Name); diff --git a/test/Microsoft.OpenApi.Tests/Reader/MapNodeTests.cs b/test/Microsoft.OpenApi.Tests/Reader/MapNodeTests.cs index 02068801e..65cce8229 100644 --- a/test/Microsoft.OpenApi.Tests/Reader/MapNodeTests.cs +++ b/test/Microsoft.OpenApi.Tests/Reader/MapNodeTests.cs @@ -1,20 +1,26 @@ -using System.Linq; -using System.Text.Json.Nodes; +using System.Text.Json.Nodes; using Microsoft.OpenApi.Reader; using Xunit; namespace Microsoft.OpenApi.Tests.Reader; -public class MapNodeTests +public class JsonNodeHelperTests { [Fact] public void DoesNotFailOnNullValue() { - var jsonNode = JsonNode.Parse("{\"key\": null}"); - var mapNode = new MapNode(new ParsingContext(new()), jsonNode); + var jsonObject = JsonNode.Parse("{\"key\": null}")?.AsObject(); + var context = new ParsingContext(new()); + JsonNode actual = null; - Assert.NotNull(mapNode); - Assert.Single(mapNode); - Assert.True(mapNode.First().Value.JsonNode.IsJsonNullSentinel()); + jsonObject.ParseMap( + new object(), + new FixedFieldMap(), + new PatternFieldMap(), + new OpenApiDocument(), + context, + (_, _, value) => actual = value); + + Assert.True(actual.IsJsonNullSentinel()); } } From b89134f888f148ae3968ccfa81d144709ba224cc Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 26 May 2026 10:39:36 -0400 Subject: [PATCH 2/4] chore(reader): prune unused JsonNode helpers Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Reader/JsonNodeHelper.cs | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs b/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs index f8d64e579..c40495013 100644 --- a/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs +++ b/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs @@ -5,9 +5,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Text.Json; using System.Text.Json.Nodes; -using System.Text.Json.Serialization; namespace Microsoft.OpenApi.Reader { @@ -162,11 +160,6 @@ public static JsonNode CreateAny(this JsonNode? node) return node ?? JsonNullSentinel.JsonNull; } - public static string GetRaw(this JsonNode node) - { - return JsonSerializer.Serialize(node, SourceGenerationContext.Default.JsonNode); - } - public static string? GetScalarValue(this JsonNode? node) { var scalarNode = node is JsonValue value ? value : throw new OpenApiException("Expected scalar value."); @@ -184,16 +177,6 @@ public static string GetRaw(this JsonNode node) return jsonObject.TryGetPropertyValue("$id", out var idNode) ? idNode?.GetScalarValue() : null; } - public static string? GetSummaryValue(this JsonObject jsonObject) - { - return jsonObject.TryGetPropertyValue("summary", out var summaryNode) ? summaryNode?.GetScalarValue() : null; - } - - public static string? GetDescriptionValue(this JsonObject jsonObject) - { - return jsonObject.TryGetPropertyValue("description", out var descriptionNode) ? descriptionNode?.GetScalarValue() : null; - } - public static void ParseMap( this JsonObject? JsonObject, T domainObject, @@ -288,7 +271,4 @@ private static void ParseField( } } } - - [JsonSerializable(typeof(JsonNode))] - internal partial class SourceGenerationContext : JsonSerializerContext { } } From 45b3c1365c4bada3c27d89a722d3a5a7d47a3c16 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 26 May 2026 10:54:37 -0400 Subject: [PATCH 3/4] chore(reader): remove CreateAny helper Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs | 7 +------ .../Reader/V2/OpenApiHeaderDeserializer.cs | 2 +- .../Reader/V2/OpenApiParameterDeserializer.cs | 2 +- .../Reader/V2/OpenApiResponseDeserializer.cs | 4 ++-- .../Reader/V2/OpenApiSchemaDeserializer.cs | 4 ++-- src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs | 6 +++--- .../Reader/V3/OpenApiExampleDeserializer.cs | 4 ++-- .../Reader/V3/OpenApiHeaderDeserializer.cs | 2 +- .../Reader/V3/OpenApiMediaTypeDeserializer.cs | 2 +- .../Reader/V3/OpenApiParameterDeserializer.cs | 2 +- .../Reader/V3/OpenApiSchemaDeserializer.cs | 4 ++-- src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs | 8 ++++---- .../Reader/V31/OpenApiExampleDeserializer.cs | 4 ++-- .../Reader/V31/OpenApiHeaderDeserializer.cs | 2 +- .../Reader/V31/OpenApiMediaTypeDeserializer.cs | 2 +- .../Reader/V31/OpenApiParameterDeserializer.cs | 2 +- .../Reader/V31/OpenApiSchemaDeserializer.cs | 4 ++-- .../Reader/V31/OpenApiV31Deserializer.cs | 8 ++++---- .../Reader/V32/OpenApiExampleDeserializer.cs | 5 ++--- .../Reader/V32/OpenApiHeaderDeserializer.cs | 3 +-- .../Reader/V32/OpenApiMediaTypeDeserializer.cs | 3 +-- .../Reader/V32/OpenApiParameterDeserializer.cs | 3 +-- .../Reader/V32/OpenApiSchemaDeserializer.cs | 4 ++-- .../Reader/V32/OpenApiV32Deserializer.cs | 8 ++++---- 24 files changed, 43 insertions(+), 52 deletions(-) diff --git a/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs b/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs index c40495013..5b3df0c82 100644 --- a/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs +++ b/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs @@ -42,7 +42,7 @@ public static List CreateListOfAny(this JsonNode? node, ParsingContext throw new OpenApiReaderException("Cannot create a list from this type of node.", context); } - return jsonArray.OfType().Select(static n => n.CreateAny()).Where(static i => i != null).ToList(); + return jsonArray.OfType().ToList(); } public static List CreateSimpleList(this JsonNode? node, Func map, OpenApiDocument? openApiDocument, ParsingContext context) @@ -155,11 +155,6 @@ public static Dictionary> CreateArrayMap(this JsonNode? no return nodes.ToDictionary(kvp => kvp.key, kvp => kvp.values); } - public static JsonNode CreateAny(this JsonNode? node) - { - return node ?? JsonNullSentinel.JsonNull; - } - public static string? GetScalarValue(this JsonNode? node) { var scalarNode = node is JsonValue value ? value : throw new OpenApiException("Expected scalar value."); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs index 758f0d39a..2da2b8f30 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs @@ -52,7 +52,7 @@ internal static partial class OpenApiV2Deserializer }, { "default", - (o, n, _, c) => GetOrCreateSchema(o).Default = n.CreateAny() + (o, n, _, c) => GetOrCreateSchema(o).Default = n }, { "maximum", diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs index ab77e17c4..78fa79dd7 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs @@ -155,7 +155,7 @@ internal static partial class OpenApiV2Deserializer }, { "default", - (o, n, t, c) => GetOrCreateSchema(o).Default = n.CreateAny() + (o, n, t, c) => GetOrCreateSchema(o).Default = n }, { "pattern", diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs index 7aafd1e48..cd100732b 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs @@ -129,7 +129,7 @@ private static Dictionary LoadExamplesExtension(JsonNod example.Description = JsonNode.Value.GetScalarValue(); break; case "value": - example.Value = JsonNode.Value.CreateAny(); + example.Value = JsonNode.Value ?? JsonNullSentinel.JsonNull; break; case "externalValue": example.ExternalValue = JsonNode.Value.GetScalarValue(); @@ -155,7 +155,7 @@ private static void LoadExamples(OpenApiResponse response, JsonNode node, OpenAp private static void LoadExample(OpenApiResponse response, string mediaType, JsonNode? node, ParsingContext context) { - var exampleNode = node.CreateAny(); + var exampleNode = node ?? JsonNullSentinel.JsonNull; response.Content ??= new Dictionary(); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs index a22853a01..32fdbcd1d 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs @@ -208,7 +208,7 @@ internal static partial class OpenApiV2Deserializer }, { "default", - (o, n, _, c) => o.Default = n.CreateAny() + (o, n, _, c) => o.Default = n }, { "discriminator", (o, n, _, c) => @@ -240,7 +240,7 @@ internal static partial class OpenApiV2Deserializer }, { "example", - (o, n, _, c) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n }, { OpenApiConstants.PatternPropertiesExtension, diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs index 9bb20a3bb..114e0a5f1 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs @@ -60,7 +60,7 @@ private static void ProcessAnyFields( public static JsonNode LoadAny(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - return node.CreateAny(); + return node; } private static IOpenApiExtension LoadExtension(string name, JsonNode node, ParsingContext context) @@ -69,7 +69,7 @@ private static IOpenApiExtension LoadExtension(string name, JsonNode node, Parsi { try { - return parser(node.CreateAny(), OpenApiSpecVersion.OpenApi2_0); + return parser(node, OpenApiSpecVersion.OpenApi2_0); } catch (OpenApiException ex) { @@ -78,7 +78,7 @@ private static IOpenApiExtension LoadExtension(string name, JsonNode node, Parsi } } - return new JsonNodeExtension(node.CreateAny()); + return new JsonNodeExtension(node); } private static string? LoadString(JsonNode node) diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiExampleDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiExampleDeserializer.cs index a920b4072..c8558b9fe 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiExampleDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiExampleDeserializer.cs @@ -25,7 +25,7 @@ internal static partial class OpenApiV3Deserializer }, { "value", - (o, n, _, c) => o.Value = n.CreateAny() + (o, n, _, c) => o.Value = n }, { "externalValue", @@ -36,7 +36,7 @@ internal static partial class OpenApiV3Deserializer private static readonly PatternFieldMap _examplePatternFields = new() { - {s => s.Equals("x-oai-dataValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.DataValue = n.CreateAny()}, + {s => s.Equals("x-oai-dataValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.DataValue = n}, {s => s.Equals("x-oai-serializedValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.SerializedValue = n.GetScalarValue()}, {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs index 802d739d6..363d1aa23 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs @@ -101,7 +101,7 @@ internal static partial class OpenApiV3Deserializer }, { "example", - (o, n, _, c) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n }, }; diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs index a0af853ff..eb772fe9d 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs @@ -26,7 +26,7 @@ internal static partial class OpenApiV3Deserializer }, { OpenApiConstants.Example, - (o, n, _, c) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n }, { OpenApiConstants.Encoding, diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs index b740360cc..25aa165f0 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs @@ -114,7 +114,7 @@ internal static partial class OpenApiV3Deserializer }, { "example", - (o, n, _, c) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n }, }; diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs index 096e6e564..b653f8d1e 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs @@ -214,7 +214,7 @@ internal static partial class OpenApiV3Deserializer }, { "default", - (o, n, _, c) => o.Default = n.CreateAny() + (o, n, _, c) => o.Default = n }, { "nullable", @@ -265,7 +265,7 @@ internal static partial class OpenApiV3Deserializer }, { "example", - (o, n, _, c) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n }, { "deprecated", diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs index ffed6ae7b..fe0514d38 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs @@ -115,14 +115,14 @@ private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(JsonN return new() { - Any = node.CreateAny() + Any = node }; } public static JsonNodeExtension LoadAny(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - return new JsonNodeExtension(node.CreateAny()); + return new JsonNodeExtension(node); } private static IOpenApiExtension LoadExtension(string name, JsonNode node, ParsingContext context) @@ -131,7 +131,7 @@ private static IOpenApiExtension LoadExtension(string name, JsonNode node, Parsi { try { - var result = parser(node.CreateAny(), OpenApiSpecVersion.OpenApi3_0); + var result = parser(node, OpenApiSpecVersion.OpenApi3_0); if (result is { }) { return result; @@ -144,7 +144,7 @@ private static IOpenApiExtension LoadExtension(string name, JsonNode node, Parsi } } - return new JsonNodeExtension(node.CreateAny()); + return new JsonNodeExtension(node); } private static string? LoadString(JsonNode node) diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiExampleDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiExampleDeserializer.cs index b6e522eb2..5ad1f4385 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiExampleDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiExampleDeserializer.cs @@ -26,7 +26,7 @@ internal static partial class OpenApiV31Deserializer { "value", (o, n, _, c) => { - o.Value = n.CreateAny(); + o.Value = n; } }, { @@ -41,7 +41,7 @@ internal static partial class OpenApiV31Deserializer private static readonly PatternFieldMap _examplePatternFields = new() { - {s => s.Equals("x-oai-dataValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.DataValue = n.CreateAny()}, + {s => s.Equals("x-oai-dataValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.DataValue = n}, {s => s.Equals("x-oai-serializedValue", StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.SerializedValue = n.GetScalarValue()}, {s => s.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase), (o, p, n, _, c) => o.AddExtension(p, LoadExtension(p, n, c))} }; diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs index 0901c82ff..7bb4848b0 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs @@ -103,7 +103,7 @@ internal static partial class OpenApiV31Deserializer { "example", (o, n, _, c) => { - o.Example = n.CreateAny(); + o.Example = n; } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiMediaTypeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiMediaTypeDeserializer.cs index 7243d7680..207c07680 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiMediaTypeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiMediaTypeDeserializer.cs @@ -27,7 +27,7 @@ internal static partial class OpenApiV31Deserializer { OpenApiConstants.Example, (o, n, _, c) => { - o.Example = n.CreateAny(); + o.Example = n; } }, { diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs index 648fdec3a..d0e7342a2 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs @@ -119,7 +119,7 @@ internal static partial class OpenApiV31Deserializer { "example", (o, n, _, c) => { - o.Example = n.CreateAny(); + o.Example = n; } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs index 2e3c3d2a2..c0c1c0488 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs @@ -273,7 +273,7 @@ internal static partial class OpenApiV31Deserializer }, { "default", - (o, n, _, c) => o.Default = n.CreateAny() + (o, n, _, c) => o.Default = n }, { "nullable", @@ -329,7 +329,7 @@ internal static partial class OpenApiV31Deserializer }, { "example", - (o, n, _, c) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n }, { "examples", diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs index 36a2f9df5..c242ce54f 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs @@ -114,13 +114,13 @@ private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(JsonN return new RuntimeExpressionAnyWrapper { - Any = node.CreateAny() + Any = node }; } public static JsonNode LoadAny(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - return node.CreateAny(); + return node; } private static IOpenApiExtension LoadExtension(string name, JsonNode node, ParsingContext context) @@ -129,7 +129,7 @@ private static IOpenApiExtension LoadExtension(string name, JsonNode node, Parsi { try { - return parser(node.CreateAny(), OpenApiSpecVersion.OpenApi3_1); + return parser(node, OpenApiSpecVersion.OpenApi3_1); } catch (OpenApiException ex) { @@ -138,7 +138,7 @@ private static IOpenApiExtension LoadExtension(string name, JsonNode node, Parsi } } - return new JsonNodeExtension(node.CreateAny()); + return new JsonNodeExtension(node); } private static string? LoadString(JsonNode node) diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiExampleDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiExampleDeserializer.cs index 2af74a472..5a5926b06 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiExampleDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiExampleDeserializer.cs @@ -26,7 +26,7 @@ internal static partial class OpenApiV32Deserializer { "value", (o, n, _, c) => { - o.Value = n.CreateAny(); + o.Value = n; } }, { @@ -38,7 +38,7 @@ internal static partial class OpenApiV32Deserializer { "dataValue", (o, n, _, c) => { - o.DataValue = n.CreateAny(); + o.DataValue = n; } }, { @@ -76,4 +76,3 @@ public static IOpenApiExample LoadExample(JsonNode node, OpenApiDocument hostDoc } } } - diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiHeaderDeserializer.cs index 5baa14a33..923b88192 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiHeaderDeserializer.cs @@ -103,7 +103,7 @@ internal static partial class OpenApiV32Deserializer { "example", (o, n, _, c) => { - o.Example = n.CreateAny(); + o.Example = n; } }, }; @@ -133,4 +133,3 @@ public static IOpenApiHeader LoadHeader(JsonNode node, OpenApiDocument hostDocum } } } - diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiMediaTypeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiMediaTypeDeserializer.cs index e65adc0de..aa16a6ffd 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiMediaTypeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiMediaTypeDeserializer.cs @@ -33,7 +33,7 @@ internal static partial class OpenApiV32Deserializer { OpenApiConstants.Example, (o, n, _, c) => { - o.Example = n.CreateAny(); + o.Example = n; } }, { @@ -111,4 +111,3 @@ public static IOpenApiMediaType LoadMediaType(JsonNode node, OpenApiDocument hos } } } - diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiParameterDeserializer.cs index 773467889..14206355f 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiParameterDeserializer.cs @@ -119,7 +119,7 @@ internal static partial class OpenApiV32Deserializer { "example", (o, n, _, c) => { - o.Example = n.CreateAny(); + o.Example = n; } }, }; @@ -177,4 +177,3 @@ public static IOpenApiParameter LoadParameter(JsonNode node, OpenApiDocument hos } } } - diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiSchemaDeserializer.cs index 45899e45e..7dbf3ad71 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiSchemaDeserializer.cs @@ -273,7 +273,7 @@ internal static partial class OpenApiV32Deserializer }, { "default", - (o, n, _, c) => o.Default = n.CreateAny() + (o, n, _, c) => o.Default = n }, { "nullable", @@ -329,7 +329,7 @@ internal static partial class OpenApiV32Deserializer }, { "example", - (o, n, _, c) => o.Example = n.CreateAny() + (o, n, _, c) => o.Example = n }, { "examples", diff --git a/src/Microsoft.OpenApi/Reader/V32/OpenApiV32Deserializer.cs b/src/Microsoft.OpenApi/Reader/V32/OpenApiV32Deserializer.cs index 39c328466..01932068a 100644 --- a/src/Microsoft.OpenApi/Reader/V32/OpenApiV32Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V32/OpenApiV32Deserializer.cs @@ -114,13 +114,13 @@ private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(JsonN return new RuntimeExpressionAnyWrapper { - Any = node.CreateAny() + Any = node }; } public static JsonNode LoadAny(JsonNode node, OpenApiDocument hostDocument, ParsingContext context) { - return node.CreateAny(); + return node; } private static IOpenApiExtension LoadExtension(string name, JsonNode node, ParsingContext context) @@ -129,7 +129,7 @@ private static IOpenApiExtension LoadExtension(string name, JsonNode node, Parsi { try { - return parser(node.CreateAny(), OpenApiSpecVersion.OpenApi3_2); + return parser(node, OpenApiSpecVersion.OpenApi3_2); } catch (OpenApiException ex) { @@ -138,7 +138,7 @@ private static IOpenApiExtension LoadExtension(string name, JsonNode node, Parsi } } - return new JsonNodeExtension(node.CreateAny()); + return new JsonNodeExtension(node); } private static string? LoadString(JsonNode node) From a2858a9fafcca8a749d4104e5acf65ef94e12fa1 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 26 May 2026 12:14:13 -0400 Subject: [PATCH 4/4] chore(benchmark): update performance reports Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../performance.Descriptions-report-github.md | 24 +++---- .../performance.Descriptions-report.csv | 12 ++-- .../performance.Descriptions-report.html | 24 +++---- .../performance.Descriptions-report.json | 2 +- .../performance.EmptyModels-report-github.md | 68 +++++++++---------- .../performance.EmptyModels-report.csv | 56 +++++++-------- .../performance.EmptyModels-report.html | 66 +++++++++--------- .../performance.EmptyModels-report.json | 2 +- 8 files changed, 127 insertions(+), 127 deletions(-) diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md index d190a20d0..9b5931f81 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md @@ -1,20 +1,20 @@ ``` -BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat) -Intel Xeon Platinum 8370C CPU 2.80GHz, 1 CPU, 4 logical and 2 physical cores +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8457/25H2/2025Update/HudsonValley2) +Snapdragon X 12-core X1E80100 3.40 GHz (Max: 3.42GHz), 1 CPU, 12 logical and 12 physical cores .NET SDK 10.0.300 - [Host] : .NET 8.0.27 (8.0.27, 8.0.2726.22922), X64 RyuJIT x86-64-v4 - ShortRun : .NET 8.0.27 (8.0.27, 8.0.2726.22922), X64 RyuJIT x86-64-v4 + [Host] : .NET 8.0.27 (8.0.27, 8.0.2726.22922), Arm64 RyuJIT armv8.0-a + ShortRun : .NET 8.0.27 (8.0.27, 8.0.2726.22922), Arm64 RyuJIT armv8.0-a Job=ShortRun IterationCount=3 LaunchCount=1 WarmupCount=3 ``` -| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | -|------------- |---------------:|--------------:|------------:|-----------:|-----------:|----------:|-------------:| -| PetStoreYaml | 480.2 μs | 50.16 μs | 2.75 μs | 11.7188 | - | - | 363.98 KB | -| PetStoreJson | 215.4 μs | 27.68 μs | 1.52 μs | 8.7891 | 1.9531 | - | 225.84 KB | -| GHESYaml | 1,034,639.0 μs | 99,755.13 μs | 5,467.92 μs | 17000.0000 | 14000.0000 | 3000.0000 | 345962.32 KB | -| GHESJson | 414,562.3 μs | 57,822.66 μs | 3,169.46 μs | 8000.0000 | 6000.0000 | 1000.0000 | 207483.96 KB | -| GHESNextYaml | 1,233,870.1 μs | 138,213.19 μs | 7,575.93 μs | 25000.0000 | 15000.0000 | 3000.0000 | 542594.95 KB | -| GHESNextJson | 649,688.9 μs | 72,965.05 μs | 3,999.46 μs | 16000.0000 | 8000.0000 | 1000.0000 | 407786.32 KB | +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | +|------------- |-------------:|--------------:|-------------:|-----------:|-----------:|----------:|-------------:| +| PetStoreYaml | 276.3 μs | 38.27 μs | 2.10 μs | 74.2188 | 11.7188 | - | 305.91 KB | +| PetStoreJson | 112.8 μs | 2.80 μs | 0.15 μs | 41.0156 | 0.4883 | - | 168.05 KB | +| GHESYaml | 608,668.3 μs | 188,763.29 μs | 10,346.75 μs | 44000.0000 | 18000.0000 | 3000.0000 | 250121.85 KB | +| GHESJson | 244,147.6 μs | 361,794.79 μs | 19,831.19 μs | 17000.0000 | 9000.0000 | 2000.0000 | 107293.42 KB | +| GHESNextYaml | 765,440.1 μs | 23,162.26 μs | 1,269.60 μs | 79000.0000 | 20000.0000 | 3000.0000 | 443655.46 KB | +| GHESNextJson | 435,329.2 μs | 241,612.89 μs | 13,243.62 μs | 51000.0000 | 11000.0000 | 2000.0000 | 305423.41 KB | diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv index 8ce3ff619..6ca713e4b 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv @@ -1,7 +1,7 @@ Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Gen0,Gen1,Gen2,Allocated -PetStoreYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,480.2 μs,50.16 μs,2.75 μs,11.7188,0.0000,0.0000,363.98 KB -PetStoreJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,215.4 μs,27.68 μs,1.52 μs,8.7891,1.9531,0.0000,225.84 KB -GHESYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"1,034,639.0 μs","99,755.13 μs","5,467.92 μs",17000.0000,14000.0000,3000.0000,345962.32 KB -GHESJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"414,562.3 μs","57,822.66 μs","3,169.46 μs",8000.0000,6000.0000,1000.0000,207483.96 KB -GHESNextYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"1,233,870.1 μs","138,213.19 μs","7,575.93 μs",25000.0000,15000.0000,3000.0000,542594.95 KB -GHESNextJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"649,688.9 μs","72,965.05 μs","3,999.46 μs",16000.0000,8000.0000,1000.0000,407786.32 KB +PetStoreYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,276.3 μs,38.27 μs,2.10 μs,74.2188,11.7188,0.0000,305.91 KB +PetStoreJson,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,112.8 μs,2.80 μs,0.15 μs,41.0156,0.4883,0.0000,168.05 KB +GHESYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"608,668.3 μs","188,763.29 μs","10,346.75 μs",44000.0000,18000.0000,3000.0000,250121.85 KB +GHESJson,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"244,147.6 μs","361,794.79 μs","19,831.19 μs",17000.0000,9000.0000,2000.0000,107293.42 KB +GHESNextYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"765,440.1 μs","23,162.26 μs","1,269.60 μs",79000.0000,20000.0000,3000.0000,443655.46 KB +GHESNextJson,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"435,329.2 μs","241,612.89 μs","13,243.62 μs",51000.0000,11000.0000,2000.0000,305423.41 KB diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html index 9cd26a52f..a6a592c7b 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html @@ -2,7 +2,7 @@ -performance.Descriptions-20260526-145612 +performance.Descriptions-20260526-120411