diff --git a/src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs b/src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs index f263dae0e..b46e0b2a6 100644 --- a/src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs +++ b/src/Microsoft.OpenApi.Hidi/Formatters/PowerShellFormatter.cs @@ -54,7 +54,7 @@ public override void Visit(IOpenApiSchema schema) public override void Visit(IOpenApiPathItem pathItem) { - if (pathItem.Operations.TryGetValue(HttpMethod.Put, out var value) && + if (pathItem.Operations is not null && pathItem.Operations.TryGetValue(HttpMethod.Put, out var value) && value.OperationId != null) { var operationId = value.OperationId; @@ -150,7 +150,7 @@ private static string RemoveKeyTypeSegment(string operationId, IList parameter private void AddAdditionalPropertiesToSchema(IOpenApiSchema schema) { - if (schema is OpenApiSchema openApiSchema && !_schemaLoop.Contains(schema) && schema.Type.Equals(JsonSchemaType.Object)) + if (schema is OpenApiSchema openApiSchema + && !_schemaLoop.Contains(schema) + && schema.Type.Equals(JsonSchemaType.Object)) { openApiSchema.AdditionalProperties = new OpenApiSchema() { Type = JsonSchemaType.Object }; @@ -187,7 +189,10 @@ private void AddAdditionalPropertiesToSchema(IOpenApiSchema schema) * we need a way to keep track of visited schemas to avoid * endlessly creating and walking them in an infinite recursion. */ - _schemaLoop.Push(schema.AdditionalProperties); + if (schema.AdditionalProperties is not null) + { + _schemaLoop.Push(schema.AdditionalProperties); + } } } diff --git a/src/Microsoft.OpenApi.Hidi/OpenApiService.cs b/src/Microsoft.OpenApi.Hidi/OpenApiService.cs index e0cce5896..7cdf9a2cb 100644 --- a/src/Microsoft.OpenApi.Hidi/OpenApiService.cs +++ b/src/Microsoft.OpenApi.Hidi/OpenApiService.cs @@ -94,7 +94,7 @@ public static async Task TransformOpenApiDocumentAsync(HidiOptions options, ILog // Load OpenAPI document var document = await GetOpenApiAsync(options, openApiFormat.GetDisplayName(), logger, options.MetadataVersion, cancellationToken).ConfigureAwait(false); - if (options.FilterOptions != null) + if (options.FilterOptions != null && document is not null) { document = ApplyFilters(options, logger, apiDependency, postmanCollection, document); } @@ -107,7 +107,11 @@ public static async Task TransformOpenApiDocumentAsync(HidiOptions options, ILog var walker = new OpenApiWalker(powerShellFormatter); walker.Walk(document); } - await WriteOpenApiAsync(options, openApiFormat, openApiVersion, document, logger, cancellationToken).ConfigureAwait(false); + if (document is not null) + { + // Write the OpenAPI document to the output file + await WriteOpenApiAsync(options, openApiFormat, openApiVersion, document, logger, cancellationToken).ConfigureAwait(false); + } } catch (TaskCanceledException) { @@ -172,7 +176,7 @@ private static OpenApiDocument ApplyFilters(HidiOptions options, ILogger logger, options.FilterOptions.FilterByTags, requestUrls, document, - logger); + logger); if (predicate != null) { var stopwatch = new Stopwatch(); @@ -210,6 +214,7 @@ private static async Task WriteOpenApiAsync(HidiOptions options, OpenApiFormat o var stopwatch = new Stopwatch(); stopwatch.Start(); + await document.SerializeAsync(writer, openApiVersion, cancellationToken).ConfigureAwait(false); stopwatch.Stop(); @@ -219,9 +224,9 @@ private static async Task WriteOpenApiAsync(HidiOptions options, OpenApiFormat o } // Get OpenAPI document either from OpenAPI or CSDL - private static async Task GetOpenApiAsync(HidiOptions options, string format, ILogger logger, string? metadataVersion = null, CancellationToken cancellationToken = default) + private static async Task GetOpenApiAsync(HidiOptions options, string format, ILogger logger, string? metadataVersion = null, CancellationToken cancellationToken = default) { - OpenApiDocument document; + OpenApiDocument? document; Stream stream; if (!string.IsNullOrEmpty(options.Csdl)) @@ -242,7 +247,7 @@ private static async Task GetOpenApiAsync(HidiOptions options, document = await ConvertCsdlToOpenApiAsync(filteredStream ?? stream, format, metadataVersion, options.SettingsConfig, cancellationToken).ConfigureAwait(false); stopwatch.Stop(); - logger.LogTrace("{Timestamp}ms: Generated OpenAPI with {Paths} paths.", stopwatch.ElapsedMilliseconds, document.Paths.Count); + logger.LogTrace("{Timestamp}ms: Generated OpenAPI with {Paths} paths.", stopwatch.ElapsedMilliseconds, document?.Paths.Count); } } else if (!string.IsNullOrEmpty(options.OpenApi)) @@ -370,7 +375,7 @@ private static MemoryStream ApplyFilterToCsdl(Stream csdlStream, string entitySe if (result is null) return null; - return result.Diagnostic.Errors.Count == 0; + return result.Diagnostic?.Errors.Count == 0; } private static async Task ParseOpenApiAsync(string openApiFile, bool inlineExternal, ILogger logger, Stream stream, CancellationToken cancellationToken = default) @@ -407,7 +412,7 @@ private static async Task ParseOpenApiAsync(string openApiFile, bool /// /// The CSDL stream. /// An OpenAPI document. - public static async Task ConvertCsdlToOpenApiAsync(Stream csdl, string format, string? metadataVersion = null, IConfiguration? settings = null, CancellationToken token = default) + public static async Task ConvertCsdlToOpenApiAsync(Stream csdl, string format, string? metadataVersion = null, IConfiguration? settings = null, CancellationToken token = default) { using var reader = new StreamReader(csdl); var csdlText = await reader.ReadToEndAsync(token).ConfigureAwait(false); @@ -425,7 +430,7 @@ public static async Task ConvertCsdlToOpenApiAsync(Stream csdl, /// /// The converted OpenApiDocument. /// A valid OpenApiDocument instance. - public static OpenApiDocument FixReferences(OpenApiDocument document, string format) + public static OpenApiDocument? FixReferences(OpenApiDocument document, string format) { // This method is only needed because the output of ConvertToOpenApi isn't quite a valid OpenApiDocument instance. // So we write it out, and read it back in again to fix it up. @@ -584,52 +589,54 @@ private static string GetInputPathExtension(string? openapi = null, string? csdl var openApiFormat = options.OpenApiFormat ?? (!string.IsNullOrEmpty(options.OpenApi) ? GetOpenApiFormat(options.OpenApi, logger) : OpenApiFormat.Yaml); var document = await GetOpenApiAsync(options, openApiFormat.GetDisplayName(), logger, null, cancellationToken).ConfigureAwait(false); - - using (logger.BeginScope("Creating diagram")) + if (document is not null) { - // If output is null, create a HTML file in the user's temporary directory - var sourceUrl = (string.IsNullOrEmpty(options.OpenApi), string.IsNullOrEmpty(options.Csdl)) switch { - (false, _) => options.OpenApi!, - (_, false) => options.Csdl!, - _ => throw new InvalidOperationException("No input file path or URL provided") - }; - if (options.Output == null) + using (logger.BeginScope("Creating diagram")) { - var tempPath = Path.GetTempPath() + "/hidi/"; - if (!File.Exists(tempPath)) + // If output is null, create a HTML file in the user's temporary directory + var sourceUrl = (string.IsNullOrEmpty(options.OpenApi), string.IsNullOrEmpty(options.Csdl)) switch { - Directory.CreateDirectory(tempPath); - } - - var fileName = Path.GetRandomFileName(); - - var output = new FileInfo(Path.Combine(tempPath, fileName + ".html")); - using (var file = new FileStream(output.FullName, FileMode.Create)) + (false, _) => options.OpenApi!, + (_, false) => options.Csdl!, + _ => throw new InvalidOperationException("No input file path or URL provided") + }; + if (options.Output == null) { - using var writer = new StreamWriter(file); - WriteTreeDocumentAsHtml(sourceUrl, document, writer); + var tempPath = Path.GetTempPath() + "/hidi/"; + if (!File.Exists(tempPath)) + { + Directory.CreateDirectory(tempPath); + } + + var fileName = Path.GetRandomFileName(); + + var output = new FileInfo(Path.Combine(tempPath, fileName + ".html")); + using (var file = new FileStream(output.FullName, FileMode.Create)) + { + using var writer = new StreamWriter(file); + WriteTreeDocumentAsHtml(sourceUrl, document, writer); + } + logger.LogTrace("Created Html document with diagram "); + + // Launch a browser to display the output html file + using var process = new Process(); + process.StartInfo.FileName = output.FullName; + process.StartInfo.UseShellExecute = true; + process.Start(); + + return output.FullName; } - logger.LogTrace("Created Html document with diagram "); - - // Launch a browser to display the output html file - using var process = new Process(); - process.StartInfo.FileName = output.FullName; - process.StartInfo.UseShellExecute = true; - process.Start(); - - return output.FullName; - } - else // Write diagram as Markdown document to output file - { - using (var file = new FileStream(options.Output.FullName, FileMode.Create)) + else // Write diagram as Markdown document to output file { + using var file = new FileStream(options.Output.FullName, FileMode.Create); using var writer = new StreamWriter(file); WriteTreeDocumentAsMarkdown(sourceUrl, document, writer); + + logger.LogTrace("Created markdown document with diagram "); + return options.Output.FullName; } - logger.LogTrace("Created markdown document with diagram "); - return options.Output.FullName; } - } + } } catch (TaskCanceledException) { @@ -645,7 +652,7 @@ private static string GetInputPathExtension(string? openapi = null, string? csdl private static void LogErrors(ILogger logger, ReadResult result) { var context = result.Diagnostic; - if (context.Errors.Count != 0) + if (context is not null && context.Errors.Count != 0) { using (logger.BeginScope("Detected errors")) { @@ -697,7 +704,7 @@ internal static void WriteTreeDocumentAsHtml(string sourceUrl, OpenApiDocument d """); - writer.WriteLine("

" + document.Info.Title + "

"); + writer.WriteLine("

" + document?.Info.Title + "

"); writer.WriteLine(); writer.WriteLine($"

API Description: {sourceUrl}

"); @@ -751,7 +758,7 @@ internal static async Task PluginManifestAsync(HidiOptions options, ILogger logg cancellationToken.ThrowIfCancellationRequested(); - if (options.FilterOptions != null) + if (options.FilterOptions != null && document is not null) { document = ApplyFilters(options, logger, apiDependency, null, document); } @@ -765,24 +772,31 @@ internal static async Task PluginManifestAsync(HidiOptions options, ILogger logg // Write OpenAPI to Output folder options.Output = new(Path.Combine(options.OutputFolder, "openapi.json")); options.TerseOutput = true; - await WriteOpenApiAsync(options, OpenApiFormat.Json, OpenApiSpecVersion.OpenApi3_1, document, logger, cancellationToken).ConfigureAwait(false); - - // Create OpenAIPluginManifest from ApiDependency and OpenAPI document - var manifest = new OpenAIPluginManifest(document.Info?.Title ?? "Title", document.Info?.Title ?? "Title", "https://go.microsoft.com/fwlink/?LinkID=288890", document.Info?.Contact?.Email ?? "placeholder@contoso.com", document.Info?.License?.Url.ToString() ?? "https://placeholderlicenseurl.com") - { - DescriptionForHuman = document.Info?.Description ?? "Description placeholder", - Api = new("openapi", "./openapi.json"), - Auth = new ManifestNoAuth(), - }; - manifest.NameForModel = manifest.NameForHuman; - manifest.DescriptionForModel = manifest.DescriptionForHuman; - - // Write OpenAIPluginManifest to Output folder - var manifestFile = new FileInfo(Path.Combine(options.OutputFolder, "ai-plugin.json")); - using var file = new FileStream(manifestFile.FullName, FileMode.Create); - using var jsonWriter = new Utf8JsonWriter(file, new() { Indented = true }); - manifest.Write(jsonWriter); - await jsonWriter.FlushAsync(cancellationToken).ConfigureAwait(false); + if (document is not null) + { + await WriteOpenApiAsync(options, OpenApiFormat.Json, OpenApiSpecVersion.OpenApi3_1, document, logger, cancellationToken).ConfigureAwait(false); + + // Create OpenAIPluginManifest from ApiDependency and OpenAPI document + var manifest = new OpenAIPluginManifest(document.Info.Title ?? "Title", + document.Info.Title ?? "Title", + "https://go.microsoft.com/fwlink/?LinkID=288890", + document.Info?.Contact?.Email ?? "placeholder@contoso.com", + document.Info?.License?.Url?.ToString() ?? "https://placeholderlicenseurl.com") + { + DescriptionForHuman = document.Info?.Description ?? "Description placeholder", + Api = new("openapi", "./openapi.json"), + Auth = new ManifestNoAuth(), + }; + manifest.NameForModel = manifest.NameForHuman; + manifest.DescriptionForModel = manifest.DescriptionForHuman; + + // Write OpenAIPluginManifest to Output folder + var manifestFile = new FileInfo(Path.Combine(options.OutputFolder, "ai-plugin.json")); + using var file = new FileStream(manifestFile.FullName, FileMode.Create); + using var jsonWriter = new Utf8JsonWriter(file, new() { Indented = true }); + manifest.Write(jsonWriter); + await jsonWriter.FlushAsync(cancellationToken).ConfigureAwait(false); + } } } } diff --git a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj index e3a40ffb7..8e55c6487 100644 --- a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj +++ b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj @@ -11,6 +11,7 @@ true NU5048 + enable README.md diff --git a/src/Microsoft.OpenApi.Readers/OpenApiYamlReader.cs b/src/Microsoft.OpenApi.Readers/OpenApiYamlReader.cs index eba4fd248..d52be9a4a 100644 --- a/src/Microsoft.OpenApi.Readers/OpenApiYamlReader.cs +++ b/src/Microsoft.OpenApi.Readers/OpenApiYamlReader.cs @@ -84,11 +84,11 @@ public static ReadResult Read(JsonNode jsonNode, OpenApiReaderSettings settings) } /// - public T ReadFragment(MemoryStream input, + public T? ReadFragment(MemoryStream input, OpenApiSpecVersion version, OpenApiDocument openApiDocument, out OpenApiDiagnostic diagnostic, - OpenApiReaderSettings settings = null) where T : IOpenApiElement + OpenApiReaderSettings? settings = null) where T : IOpenApiElement { if (input is null) throw new ArgumentNullException(nameof(input)); JsonNode jsonNode; @@ -110,7 +110,7 @@ public T ReadFragment(MemoryStream input, } /// - public static T ReadFragment(JsonNode input, OpenApiSpecVersion version, OpenApiDocument openApiDocument, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null) where T : IOpenApiElement + public static T? ReadFragment(JsonNode input, OpenApiSpecVersion version, OpenApiDocument openApiDocument, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings? settings = null) where T : IOpenApiElement { return _jsonReader.ReadFragment(input, version, openApiDocument, out diagnostic, settings); } diff --git a/src/Microsoft.OpenApi/Exceptions/OpenApiException.cs b/src/Microsoft.OpenApi/Exceptions/OpenApiException.cs index 9c1f4233f..cb7eaecf0 100644 --- a/src/Microsoft.OpenApi/Exceptions/OpenApiException.cs +++ b/src/Microsoft.OpenApi/Exceptions/OpenApiException.cs @@ -33,7 +33,7 @@ public OpenApiException(string message) /// /// The plain text error message for this exception. /// The inner exception that is the cause of this exception to be thrown. - public OpenApiException(string message, Exception innerException) + public OpenApiException(string message, Exception? innerException) : base(message, innerException) { } @@ -46,6 +46,6 @@ public OpenApiException(string message, Exception innerException) /// a text/plain pointer as defined in https://tools.ietf.org/html/rfc5147 /// Currently only line= is provided because using char= causes tests to break due to CR/LF and LF differences /// - public string Pointer { get; set; } + public string? Pointer { get; set; } } } diff --git a/src/Microsoft.OpenApi/Exceptions/OpenApiReaderException.cs b/src/Microsoft.OpenApi/Exceptions/OpenApiReaderException.cs index 257b0e9a4..aa7866c02 100644 --- a/src/Microsoft.OpenApi/Exceptions/OpenApiReaderException.cs +++ b/src/Microsoft.OpenApi/Exceptions/OpenApiReaderException.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; @@ -34,17 +34,6 @@ public OpenApiReaderException(string message, ParsingContext context) : base(mes Pointer = context.GetLocation(); } - /// - /// Initializes the class with a message and line, column location of error. - /// - /// Plain text error message for this exception. - /// Parsing node where error occured - public OpenApiReaderException(string message, JsonNode node) : base(message) - { - // This only includes line because using a char range causes tests to break due to CR/LF & LF differences - // See https://tools.ietf.org/html/rfc5147 for syntax - } - /// /// Initializes the class with a custom message and inner exception. /// diff --git a/src/Microsoft.OpenApi/Exceptions/OpenApiWriterException.cs b/src/Microsoft.OpenApi/Exceptions/OpenApiWriterException.cs index 9e0540c53..af19269f8 100644 --- a/src/Microsoft.OpenApi/Exceptions/OpenApiWriterException.cs +++ b/src/Microsoft.OpenApi/Exceptions/OpenApiWriterException.cs @@ -33,7 +33,7 @@ public OpenApiWriterException(string message) /// /// The plain text error message for this exception. /// The inner exception that is the cause of this exception to be thrown. - public OpenApiWriterException(string message, Exception innerException) + public OpenApiWriterException(string message, Exception? innerException) : base(message, innerException) { } diff --git a/src/Microsoft.OpenApi/Expressions/BodyExpression.cs b/src/Microsoft.OpenApi/Expressions/BodyExpression.cs index c63b1bc58..a6743e715 100644 --- a/src/Microsoft.OpenApi/Expressions/BodyExpression.cs +++ b/src/Microsoft.OpenApi/Expressions/BodyExpression.cs @@ -30,7 +30,7 @@ public BodyExpression() /// Initializes a new instance of the class. /// /// a JSON Pointer [RFC 6901](https://tools.ietf.org/html/rfc6901). - public BodyExpression(JsonPointer pointer) + public BodyExpression(JsonPointer? pointer) : base(pointer?.ToString()) { Utils.CheckArgumentNull(pointer); @@ -55,6 +55,6 @@ public override string Expression /// /// Gets the fragment string. /// - public string Fragment { get => Value; } + public string? Fragment { get => Value; } } } diff --git a/src/Microsoft.OpenApi/Expressions/HeaderExpression.cs b/src/Microsoft.OpenApi/Expressions/HeaderExpression.cs index 99bbf2a96..f373960d5 100644 --- a/src/Microsoft.OpenApi/Expressions/HeaderExpression.cs +++ b/src/Microsoft.OpenApi/Expressions/HeaderExpression.cs @@ -31,6 +31,6 @@ public HeaderExpression(string token) /// /// Gets the token string. /// - public string Token { get => Value; } + public string? Token { get => Value; } } } diff --git a/src/Microsoft.OpenApi/Expressions/PathExpression.cs b/src/Microsoft.OpenApi/Expressions/PathExpression.cs index 1d43b9b21..9922b6b1f 100644 --- a/src/Microsoft.OpenApi/Expressions/PathExpression.cs +++ b/src/Microsoft.OpenApi/Expressions/PathExpression.cs @@ -31,6 +31,6 @@ public PathExpression(string name) /// /// Gets the name string. /// - public string Name { get => Value; } + public string? Name { get => Value; } } } diff --git a/src/Microsoft.OpenApi/Expressions/QueryExpression.cs b/src/Microsoft.OpenApi/Expressions/QueryExpression.cs index 55016d82a..d33f3bff6 100644 --- a/src/Microsoft.OpenApi/Expressions/QueryExpression.cs +++ b/src/Microsoft.OpenApi/Expressions/QueryExpression.cs @@ -31,6 +31,6 @@ public QueryExpression(string name) /// /// Gets the name string. /// - public string Name { get => Value; } + public string? Name { get => Value; } } } diff --git a/src/Microsoft.OpenApi/Expressions/RuntimeExpression.cs b/src/Microsoft.OpenApi/Expressions/RuntimeExpression.cs index 69aecfd37..b6104e1b3 100644 --- a/src/Microsoft.OpenApi/Expressions/RuntimeExpression.cs +++ b/src/Microsoft.OpenApi/Expressions/RuntimeExpression.cs @@ -84,7 +84,7 @@ public override int GetHashCode() /// /// Equals implementation for IEquatable. /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { return Equals(obj as RuntimeExpression); } @@ -92,7 +92,7 @@ public override bool Equals(object obj) /// /// Equals implementation for object of the same type. /// - public bool Equals(RuntimeExpression obj) + public bool Equals(RuntimeExpression? obj) { return obj != null && obj.Expression == Expression; } diff --git a/src/Microsoft.OpenApi/Expressions/SourceExpression.cs b/src/Microsoft.OpenApi/Expressions/SourceExpression.cs index 76a22f97d..36eec56f7 100644 --- a/src/Microsoft.OpenApi/Expressions/SourceExpression.cs +++ b/src/Microsoft.OpenApi/Expressions/SourceExpression.cs @@ -16,7 +16,7 @@ public abstract class SourceExpression : RuntimeExpression /// Initializes a new instance of the class. /// /// The value string. - protected SourceExpression(string value) + protected SourceExpression(string? value) { Value = value; } @@ -24,7 +24,7 @@ protected SourceExpression(string value) /// /// Gets the expression string. /// - protected string Value { get; } + protected string? Value { get; } /// /// Build the source expression from input string. diff --git a/src/Microsoft.OpenApi/Extensions/EnumExtensions.cs b/src/Microsoft.OpenApi/Extensions/EnumExtensions.cs index bc4e86783..d3ada8f1e 100644 --- a/src/Microsoft.OpenApi/Extensions/EnumExtensions.cs +++ b/src/Microsoft.OpenApi/Extensions/EnumExtensions.cs @@ -27,7 +27,7 @@ public static class EnumExtensions /// The attribute of the specified type or null. /// [UnconditionalSuppressMessage("Trimming", "IL2075", Justification = "Fields are never trimmed for enum types.")] - public static T GetAttributeOfType(this Enum enumValue) where T : Attribute + public static T? GetAttributeOfType(this Enum enumValue) where T : Attribute { var type = enumValue.GetType(); // Use GetField to get the field info for the enum value @@ -58,7 +58,7 @@ public static string GetDisplayName(this Enum enumValue) var attribute = e.GetAttributeOfType(); // Return the DisplayAttribute name if it exists, otherwise return the enum's string representation - return attribute == null ? e.ToString() : attribute.Name; + return attribute?.Name is not null ? attribute.Name : e.ToString(); }); } } diff --git a/src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs b/src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs index d0b0d9c35..e44b90be8 100644 --- a/src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs +++ b/src/Microsoft.OpenApi/Extensions/OpenApiElementExtensions.cs @@ -23,13 +23,7 @@ public static class OpenApiElementExtensions /// An IEnumerable of errors. This function will never return null. public static IEnumerable Validate(this IOpenApiElement element, ValidationRuleSet ruleSet) { - var validator = new OpenApiValidator(ruleSet); - - if (element is OpenApiDocument doc) - { - validator.HostDocument = doc; - } - + var validator = new OpenApiValidator(ruleSet); var walker = new OpenApiWalker(validator); walker.Walk(element); return validator.Errors.Cast().Union(validator.Warnings); diff --git a/src/Microsoft.OpenApi/Extensions/OpenApiExtensibleExtensions.cs b/src/Microsoft.OpenApi/Extensions/OpenApiExtensibleExtensions.cs index c8c3b2a48..01fc02020 100644 --- a/src/Microsoft.OpenApi/Extensions/OpenApiExtensibleExtensions.cs +++ b/src/Microsoft.OpenApi/Extensions/OpenApiExtensibleExtensions.cs @@ -32,7 +32,10 @@ public static void AddExtension(this T element, string name, IOpenApiExtensio throw new OpenApiException(string.Format(SRResource.ExtensionFieldNameMustBeginWithXDash, name)); } - element.Extensions[name] = Utils.CheckArgumentNull(any); + if (element.Extensions is not null) + { + element.Extensions[name] = Utils.CheckArgumentNull(any); + } } } } diff --git a/src/Microsoft.OpenApi/Extensions/OpenApiReferencableExtensions.cs b/src/Microsoft.OpenApi/Extensions/OpenApiReferencableExtensions.cs index da51f3b55..df266b577 100644 --- a/src/Microsoft.OpenApi/Extensions/OpenApiReferencableExtensions.cs +++ b/src/Microsoft.OpenApi/Extensions/OpenApiReferencableExtensions.cs @@ -32,17 +32,20 @@ public static IOpenApiReferenceable ResolveReference(this IOpenApiReferenceable var mapKey = pointer.Tokens.ElementAtOrDefault(1); try { - if (element is OpenApiHeader header) + if (propertyName is not null && mapKey is not null) { - return ResolveReferenceOnHeaderElement(header, propertyName, mapKey, pointer); - } - if (element is OpenApiParameter parameter) - { - return ResolveReferenceOnParameterElement(parameter, propertyName, mapKey, pointer); - } - if (element is OpenApiResponse response) - { - return ResolveReferenceOnResponseElement(response, propertyName, mapKey, pointer); + if (element is OpenApiHeader header) + { + return ResolveReferenceOnHeaderElement(header, propertyName, mapKey, pointer); + } + if (element is OpenApiParameter parameter) + { + return ResolveReferenceOnParameterElement(parameter, propertyName, mapKey, pointer); + } + if (element is OpenApiResponse response) + { + return ResolveReferenceOnResponseElement(response, propertyName, mapKey, pointer); + } } } catch (KeyNotFoundException) diff --git a/src/Microsoft.OpenApi/Extensions/OpenApiSerializableExtensions.cs b/src/Microsoft.OpenApi/Extensions/OpenApiSerializableExtensions.cs index 9d284db1a..d028cd5e4 100755 --- a/src/Microsoft.OpenApi/Extensions/OpenApiSerializableExtensions.cs +++ b/src/Microsoft.OpenApi/Extensions/OpenApiSerializableExtensions.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.Globalization; @@ -82,7 +82,7 @@ public static Task SerializeAsync( Stream stream, OpenApiSpecVersion specVersion, OpenApiFormat format, - OpenApiWriterSettings settings, + OpenApiWriterSettings? settings = null, CancellationToken cancellationToken = default) where T : IOpenApiSerializable { diff --git a/src/Microsoft.OpenApi/Extensions/OpenApiServerExtensions.cs b/src/Microsoft.OpenApi/Extensions/OpenApiServerExtensions.cs index b885cb235..5276876ce 100644 --- a/src/Microsoft.OpenApi/Extensions/OpenApiServerExtensions.cs +++ b/src/Microsoft.OpenApi/Extensions/OpenApiServerExtensions.cs @@ -21,37 +21,39 @@ public static class OpenApiServerExtensions /// 1. A substitution has no valid value in both the supplied dictionary and the default /// 2. A substitution's value is not available in the enum provided /// - public static string ReplaceServerUrlVariables(this OpenApiServer server, IDictionary values = null) + public static string? ReplaceServerUrlVariables(this OpenApiServer server, IDictionary? values = null) { var parsedUrl = server.Url; - foreach (var variable in server.Variables) + if (server.Variables is not null && parsedUrl is not null) { - // Try to get the value from the provided values - if (values is not { } v || !v.TryGetValue(variable.Key, out var value) || string.IsNullOrEmpty(value)) + foreach (var variable in server.Variables) { - // Fall back to the default value - value = variable.Value.Default; - } + // Try to get the value from the provided values + if (values is not { } v || !v.TryGetValue(variable.Key, out var value) || string.IsNullOrEmpty(value)) + { + // Fall back to the default value + value = variable.Value.Default; + } - // Validate value - if (string.IsNullOrEmpty(value)) - { - // According to the spec, the variable's default value is required. - // This code path should be hit when a value isn't provided & a default value isn't available - throw new ArgumentException( - string.Format(SRResource.ParseServerUrlDefaultValueNotAvailable, variable.Key), nameof(server)); - } + // Validate value + if (string.IsNullOrEmpty(value)) + { + // According to the spec, the variable's default value is required. + // This code path should be hit when a value isn't provided & a default value isn't available + throw new ArgumentException( + string.Format(SRResource.ParseServerUrlDefaultValueNotAvailable, variable.Key), nameof(server)); + } - // If an enum is provided, the array should not be empty & the value should exist in the enum - if (variable.Value.Enum is {} e && (e.Count == 0 || !e.Contains(value))) - { - throw new ArgumentException( - string.Format(SRResource.ParseServerUrlValueNotValid, value, variable.Key), nameof(values)); - } - - parsedUrl = parsedUrl.Replace($"{{{variable.Key}}}", value); - } + // If an enum is provided, the array should not be empty & the value should exist in the enum + if (value is not null && variable.Value.Enum is { } e && (e.Count == 0 || !e.Contains(value))) + { + throw new ArgumentException( + string.Format(SRResource.ParseServerUrlValueNotValid, value, variable.Key), nameof(values)); + } + parsedUrl = parsedUrl?.Replace($"{{{variable.Key}}}", value); + } + } return parsedUrl; } } diff --git a/src/Microsoft.OpenApi/Extensions/StringExtensions.cs b/src/Microsoft.OpenApi/Extensions/StringExtensions.cs index b644050ab..d88aeda87 100644 --- a/src/Microsoft.OpenApi/Extensions/StringExtensions.cs +++ b/src/Microsoft.OpenApi/Extensions/StringExtensions.cs @@ -19,7 +19,7 @@ internal static class StringExtensions { private static readonly ConcurrentDictionary> EnumDisplayCache = new(); - internal static bool TryGetEnumFromDisplayName<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>(this string displayName, ParsingContext parsingContext, out T result) where T : Enum + internal static bool TryGetEnumFromDisplayName<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>(this string? displayName, ParsingContext parsingContext, out T? result) where T : Enum { if (TryGetEnumFromDisplayName(displayName, out result)) { @@ -30,13 +30,13 @@ internal static class StringExtensions return false; } - internal static bool TryGetEnumFromDisplayName<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>(this string displayName, out T result) where T : Enum + internal static bool TryGetEnumFromDisplayName<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>(this string? displayName, out T? result) where T : Enum { var type = typeof(T); - var displayMap = EnumDisplayCache.GetOrAdd(type, _=> GetEnumValues(type)); + var displayMap = EnumDisplayCache.GetOrAdd(type, _ => GetEnumValues(type)); - if (displayMap.TryGetValue(displayName, out var cachedValue)) + if (displayName is not null && displayMap.TryGetValue(displayName, out var cachedValue)) { result = (T)cachedValue; return true; @@ -50,12 +50,14 @@ private static ReadOnlyDictionary GetEnumValues([DynamicallyA var result = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var field in enumType.GetFields(BindingFlags.Public | BindingFlags.Static)) { - if (field.GetCustomAttribute() is {} displayAttribute) + if (field.GetCustomAttribute() is { } displayAttribute + && field.GetValue(null) is T enumValue + && displayAttribute.Name is not null) { - var enumValue = (T)field.GetValue(null); result.Add(displayAttribute.Name, enumValue); } } + return new ReadOnlyDictionary(result); } internal static string ToFirstCharacterLowerCase(this string input) diff --git a/src/Microsoft.OpenApi/Helpers/JsonNodeCloneHelper.cs b/src/Microsoft.OpenApi/Helpers/JsonNodeCloneHelper.cs index caab84e7b..5daed4b39 100644 --- a/src/Microsoft.OpenApi/Helpers/JsonNodeCloneHelper.cs +++ b/src/Microsoft.OpenApi/Helpers/JsonNodeCloneHelper.cs @@ -7,9 +7,9 @@ namespace Microsoft.OpenApi.Helpers { internal static class JsonNodeCloneHelper { - internal static JsonNode Clone(JsonNode value) + internal static JsonNode? Clone(JsonNode? value) { - return value.DeepClone(); + return value?.DeepClone(); } } } diff --git a/src/Microsoft.OpenApi/Interfaces/IMetadataContainer.cs b/src/Microsoft.OpenApi/Interfaces/IMetadataContainer.cs index 2d8f26220..2ae2248de 100644 --- a/src/Microsoft.OpenApi/Interfaces/IMetadataContainer.cs +++ b/src/Microsoft.OpenApi/Interfaces/IMetadataContainer.cs @@ -14,6 +14,6 @@ public interface IMetadataContainer /// /// A collection of properties associated with the current OpenAPI element. /// - IDictionary Metadata { get; set; } + IDictionary? Metadata { get; set; } } } diff --git a/src/Microsoft.OpenApi/Interfaces/IOpenApiExtensible.cs b/src/Microsoft.OpenApi/Interfaces/IOpenApiExtensible.cs index 5531b1809..fabd1a177 100644 --- a/src/Microsoft.OpenApi/Interfaces/IOpenApiExtensible.cs +++ b/src/Microsoft.OpenApi/Interfaces/IOpenApiExtensible.cs @@ -13,6 +13,6 @@ public interface IOpenApiExtensible : IOpenApiElement /// /// Specification extensions. /// - IDictionary Extensions { get; set; } + IDictionary? Extensions { get; set; } } } diff --git a/src/Microsoft.OpenApi/Interfaces/IOpenApiReadOnlyExtensible.cs b/src/Microsoft.OpenApi/Interfaces/IOpenApiReadOnlyExtensible.cs index 367c84a96..db451d843 100644 --- a/src/Microsoft.OpenApi/Interfaces/IOpenApiReadOnlyExtensible.cs +++ b/src/Microsoft.OpenApi/Interfaces/IOpenApiReadOnlyExtensible.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Microsoft.OpenApi.Interfaces; @@ -10,6 +10,6 @@ public interface IOpenApiReadOnlyExtensible /// /// Specification extensions. /// - IDictionary Extensions { get; } + IDictionary? Extensions { get; } } diff --git a/src/Microsoft.OpenApi/Interfaces/IOpenApiReader.cs b/src/Microsoft.OpenApi/Interfaces/IOpenApiReader.cs index 3b9c85d2f..687599caa 100644 --- a/src/Microsoft.OpenApi/Interfaces/IOpenApiReader.cs +++ b/src/Microsoft.OpenApi/Interfaces/IOpenApiReader.cs @@ -40,6 +40,6 @@ public interface IOpenApiReader /// Returns diagnostic object containing errors detected during parsing. /// The OpenApiReader settings. /// Instance of newly created IOpenApiElement. - T ReadFragment(MemoryStream input, OpenApiSpecVersion version, OpenApiDocument openApiDocument, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null) where T : IOpenApiElement; + T? ReadFragment(MemoryStream input, OpenApiSpecVersion version, OpenApiDocument openApiDocument, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings? settings = null) where T : IOpenApiElement; } } diff --git a/src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceHolder.cs b/src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceHolder.cs index 6c3b0df57..37b8cae3f 100644 --- a/src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceHolder.cs +++ b/src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceHolder.cs @@ -15,11 +15,13 @@ public interface IOpenApiReferenceHolder : IOpenApiReferenceHolder whe /// /// Gets the resolved target object. /// - V Target { get; } + V? Target { get; } + /// /// Gets the recursively resolved target object. /// - T RecursiveTarget { get; } + T? RecursiveTarget { get; } + /// /// Copy the reference as a target element with overrides. /// diff --git a/src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs b/src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs index 073962a35..64049483e 100644 --- a/src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs +++ b/src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.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 Microsoft.OpenApi.Models; @@ -11,16 +11,6 @@ namespace Microsoft.OpenApi.Interfaces /// internal interface IOpenApiVersionService { - /// - /// Parse the string to a object. - /// - /// The reference string. - /// The type of the reference. - /// The summary of the reference. - /// A reference description - /// The object or null. - OpenApiReference ConvertToOpenApiReference(string reference, ReferenceType? type, string summary = null, string description = null); - /// /// Loads an OpenAPI Element from a document fragment /// @@ -28,7 +18,7 @@ internal interface IOpenApiVersionService /// document fragment node /// A host document instance. /// Instance of OpenAPIElement - T LoadElement(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement; + T? LoadElement(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement; /// /// Converts a generic RootNode instance into a strongly typed OpenApiDocument @@ -43,6 +33,6 @@ internal interface IOpenApiVersionService /// A YamlMappingNode. /// The scalar value we're parsing. /// The resulting node value. - string GetReferenceScalarValues(MapNode mapNode, string scalarValue); + string? GetReferenceScalarValues(MapNode mapNode, string scalarValue); } } diff --git a/src/Microsoft.OpenApi/Interfaces/IShallowCopyable.cs b/src/Microsoft.OpenApi/Interfaces/IShallowCopyable.cs index c1327bf0f..ecffde715 100644 --- a/src/Microsoft.OpenApi/Interfaces/IShallowCopyable.cs +++ b/src/Microsoft.OpenApi/Interfaces/IShallowCopyable.cs @@ -1,4 +1,4 @@ -namespace Microsoft.OpenApi.Interfaces; +namespace Microsoft.OpenApi.Interfaces; /// /// Interface for shallow copyable objects. /// diff --git a/src/Microsoft.OpenApi/JsonPointer.cs b/src/Microsoft.OpenApi/JsonPointer.cs index 110cca81e..627520c3b 100644 --- a/src/Microsoft.OpenApi/JsonPointer.cs +++ b/src/Microsoft.OpenApi/JsonPointer.cs @@ -39,7 +39,7 @@ private JsonPointer(string[] tokens) /// /// Gets the parent pointer. /// - public JsonPointer ParentPointer + public JsonPointer? ParentPointer { get { diff --git a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj index 5f0cb79cc..b3a511e88 100644 --- a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj +++ b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj @@ -10,6 +10,7 @@ true NU5048 + enable README.md diff --git a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiDeprecationExtension.cs b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiDeprecationExtension.cs index 6fa71600d..a61d93ce4 100644 --- a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiDeprecationExtension.cs +++ b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiDeprecationExtension.cs @@ -110,7 +110,7 @@ jsonNode is not JsonValue jsonValue || /// When the source element is not an object public static OpenApiDeprecationExtension Parse(JsonNode source) { - if (source is not JsonObject rawObject) return null; + if (source is not JsonObject rawObject) throw new ArgumentOutOfRangeException(nameof(source)); var extension = new OpenApiDeprecationExtension { RemovalDate = GetDateTimeOffsetValue(nameof(RemovalDate), rawObject), diff --git a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumValuesDescriptionExtension.cs b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumValuesDescriptionExtension.cs index 19b370518..f72479ba4 100644 --- a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumValuesDescriptionExtension.cs +++ b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumValuesDescriptionExtension.cs @@ -65,7 +65,7 @@ public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion) /// When the source element is not an object public static OpenApiEnumValuesDescriptionExtension Parse(JsonNode source) { - if (source is not JsonObject rawObject) return null; + if (source is not JsonObject rawObject) throw new ArgumentOutOfRangeException(nameof(source)); var extension = new OpenApiEnumValuesDescriptionExtension(); if (rawObject.TryGetPropertyValue("values", out var values) && values is JsonArray valuesArray) { diff --git a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPagingExtension.cs b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPagingExtension.cs index 2e9a0c3f3..340d4ed23 100644 --- a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPagingExtension.cs +++ b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPagingExtension.cs @@ -73,7 +73,7 @@ public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion) /// When the source element is not an object public static OpenApiPagingExtension Parse(JsonNode source) { - if (source is not JsonObject rawObject) return null; + if (source is not JsonObject rawObject) throw new ArgumentOutOfRangeException(nameof(source)); var extension = new OpenApiPagingExtension(); if (rawObject.TryGetPropertyValue(nameof(NextLinkName).ToFirstCharacterLowerCase(), out var nextLinkName) && nextLinkName is JsonValue nextLinkNameValue && nextLinkNameValue.TryGetValue(out var nextLinkNameStr)) { diff --git a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPrimaryErrorMessageExtension.cs b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPrimaryErrorMessageExtension.cs index a9e2f055a..aabcf0d26 100644 --- a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPrimaryErrorMessageExtension.cs +++ b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPrimaryErrorMessageExtension.cs @@ -40,7 +40,7 @@ public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion) /// The . public static OpenApiPrimaryErrorMessageExtension Parse(JsonNode source) { - if (source is not JsonValue rawObject) return null; + if (source is not JsonValue rawObject) throw new ArgumentOutOfRangeException(nameof(source)); return new() { IsPrimaryErrorMessage = rawObject.TryGetValue(out var value) && value diff --git a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiReservedParameterExtension.cs b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiReservedParameterExtension.cs index 612e4cb74..eb58c1e5c 100644 --- a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiReservedParameterExtension.cs +++ b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiReservedParameterExtension.cs @@ -42,7 +42,7 @@ public bool? IsReserved /// public static OpenApiReservedParameterExtension Parse(JsonNode source) { - if (source is not JsonValue rawBoolean) return null; + if (source is not JsonValue rawBoolean) throw new ArgumentOutOfRangeException(nameof(source)); return new() { IsReserved = rawBoolean.TryGetValue(out var value) && value diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiCallback.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiCallback.cs index 025abca20..1b18d237b 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiCallback.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiCallback.cs @@ -1,4 +1,4 @@ - + using System.Collections.Generic; using Microsoft.OpenApi.Expressions; using Microsoft.OpenApi.Interfaces; @@ -14,5 +14,5 @@ public interface IOpenApiCallback : IOpenApiReadOnlyExtensible, IShallowCopyable /// /// A Path Item Object used to define a callback request and expected responses. /// - public Dictionary PathItems { get; } + public Dictionary? PathItems { get; } } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiDescribedElement.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiDescribedElement.cs index 3deee3d3c..e41e7d6a6 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiDescribedElement.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiDescribedElement.cs @@ -1,4 +1,4 @@ -using Microsoft.OpenApi.Interfaces; +using Microsoft.OpenApi.Interfaces; namespace Microsoft.OpenApi.Models.Interfaces; @@ -11,7 +11,7 @@ public interface IOpenApiDescribedElement : IOpenApiElement /// Long description for the example. /// CommonMark syntax MAY be used for rich text representation. /// - public string Description { get; set; } + public string? Description { get; set; } } /// @@ -23,5 +23,5 @@ public interface IOpenApiReadOnlyDescribedElement : IOpenApiElement /// Long description for the example. /// CommonMark syntax MAY be used for rich text representation. /// - public string Description { get; } + public string? Description { get; } } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiExample.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiExample.cs index 9a14aca95..b572e8e6f 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiExample.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiExample.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Nodes; +using System.Text.Json.Nodes; using Microsoft.OpenApi.Interfaces; namespace Microsoft.OpenApi.Models.Interfaces; @@ -14,7 +14,7 @@ public interface IOpenApiExample : IOpenApiDescribedElement, IOpenApiSummarizedE /// exclusive. To represent examples of media types that cannot naturally represented /// in JSON or YAML, use a string value to contain the example, escaping where necessary. /// - public JsonNode Value { get; } + public JsonNode? Value { get; } /// /// A URL that points to the literal example. @@ -22,5 +22,5 @@ public interface IOpenApiExample : IOpenApiDescribedElement, IOpenApiSummarizedE /// included in JSON or YAML documents. /// The value field and externalValue field are mutually exclusive. /// - public string ExternalValue { get; } + public string? ExternalValue { get; } } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiHeader.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiHeader.cs index 69d7ec614..c6550caa6 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiHeader.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiHeader.cs @@ -1,4 +1,4 @@ - + using System.Collections.Generic; using System.Text.Json.Nodes; using Microsoft.OpenApi.Interfaces; @@ -45,21 +45,21 @@ public interface IOpenApiHeader : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// /// The schema defining the type used for the request body. /// - public IOpenApiSchema Schema { get; } + public IOpenApiSchema? Schema { get; } /// /// Example of the media type. /// - public JsonNode Example { get; } + public JsonNode? Example { get; } /// /// Examples of the media type. /// - public IDictionary Examples { get; } + public IDictionary? Examples { get; } /// /// A map containing the representations for the header. /// - public IDictionary Content { get; } + public IDictionary? Content { get; } } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiLink.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiLink.cs index f6ee7b49d..6fc9abeb6 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiLink.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiLink.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; namespace Microsoft.OpenApi.Models.Interfaces; @@ -13,25 +13,25 @@ public interface IOpenApiLink : IOpenApiDescribedElement, IOpenApiReadOnlyExtens /// A relative or absolute reference to an OAS operation. /// This field is mutually exclusive of the operationId field, and MUST point to an Operation Object. /// - public string OperationRef { get; } + public string? OperationRef { get; } /// /// The name of an existing, resolvable OAS operation, as defined with a unique operationId. /// This field is mutually exclusive of the operationRef field. /// - public string OperationId { get; } + public string? OperationId { get; } /// /// A map representing parameters to pass to an operation as specified with operationId or identified via operationRef. /// - public IDictionary Parameters { get; } + public IDictionary? Parameters { get; } /// /// A literal value or {expression} to use as a request body when calling the target operation. /// - public RuntimeExpressionAnyWrapper RequestBody { get; } + public RuntimeExpressionAnyWrapper? RequestBody { get; } /// /// A server object to be used by the target operation. /// - public OpenApiServer Server { get; } + public OpenApiServer? Server { get; } } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs index a55ce742b..63c3a860f 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiParameter.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Text.Json.Nodes; using Microsoft.OpenApi.Interfaces; @@ -16,7 +16,7 @@ public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyE /// If in is "header" and the name field is "Accept", "Content-Type" or "Authorization", the parameter definition SHALL be ignored. /// For all other cases, the name corresponds to the parameter name used by the in property. /// - public string Name { get; } + public string? Name { get; } /// /// REQUIRED. The location of the parameter. @@ -72,7 +72,7 @@ public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyE /// /// The schema defining the type used for the parameter. /// - public IOpenApiSchema Schema { get; } + public IOpenApiSchema? Schema { get; } /// /// Examples of the media type. Each example SHOULD contain a value @@ -81,7 +81,7 @@ public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyE /// Furthermore, if referencing a schema which contains an example, /// the examples value SHALL override the example provided by the schema. /// - public IDictionary Examples { get; } + public IDictionary? Examples { get; } /// /// Example of the media type. The example SHOULD match the specified schema and encoding properties @@ -91,7 +91,7 @@ public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyE /// To represent examples of media types that cannot naturally be represented in JSON or YAML, /// a string value can contain the example with escaping where necessary. /// - public JsonNode Example { get; } + public JsonNode? Example { get; } /// /// A map containing the representations for the parameter. @@ -102,5 +102,5 @@ public interface IOpenApiParameter : IOpenApiDescribedElement, IOpenApiReadOnlyE /// When example or examples are provided in conjunction with the schema object, /// the example MUST follow the prescribed serialization strategy for the parameter. /// - public IDictionary Content { get; } + public IDictionary? Content { get; } } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiPathItem.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiPathItem.cs index d69f06473..f4348154e 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiPathItem.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiPathItem.cs @@ -14,16 +14,16 @@ public interface IOpenApiPathItem : IOpenApiDescribedElement, IOpenApiSummarized /// /// Gets the definition of operations on this path. /// - public IDictionary Operations { get; } + public IDictionary? Operations { get; } /// /// An alternative server array to service all operations in this path. /// - public IList Servers { get; } + public IList? Servers { get; } /// /// A list of parameters that are applicable for all the operations described under this path. /// These parameters can be overridden at the operation level, but cannot be removed there. /// - public IList Parameters { get; } + public IList? Parameters { get; } } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiRequestBody.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiRequestBody.cs index b03bac603..b9c8304df 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiRequestBody.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiRequestBody.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Writers; @@ -19,17 +19,17 @@ public interface IOpenApiRequestBody : IOpenApiDescribedElement, IOpenApiReadOnl /// REQUIRED. The content of the request body. The key is a media type or media type range and the value describes it. /// For requests that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/* /// - public IDictionary Content { get; } + public IDictionary? Content { get; } /// /// Converts the request body to a body parameter in preparation for a v2 serialization. /// /// The writer to use to read settings from. /// The converted OpenAPI parameter - IOpenApiParameter ConvertToBodyParameter(IOpenApiWriter writer); + IOpenApiParameter? ConvertToBodyParameter(IOpenApiWriter writer); /// /// Converts the request body to a set of form data parameters in preparation for a v2 serialization. /// /// The writer to use to read settings from /// The converted OpenAPI parameters - IEnumerable ConvertToFormDataParameters(IOpenApiWriter writer); + IEnumerable? ConvertToFormDataParameters(IOpenApiWriter writer); } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs index ee4e6df10..379526e0a 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiResponse.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; namespace Microsoft.OpenApi.Models.Interfaces; @@ -12,18 +12,18 @@ public interface IOpenApiResponse : IOpenApiDescribedElement, IOpenApiReadOnlyEx /// /// Maps a header name to its definition. /// - public IDictionary Headers { get; } + public IDictionary? Headers { get; } /// /// A map containing descriptions of potential response payloads. /// The key is a media type or media type range and the value describes it. /// - public IDictionary Content { get; } + public IDictionary? Content { get; } /// /// A map of operations links that can be followed from the response. /// The key of the map is a short name for the link, /// following the naming constraints of the names for Component Objects. /// - public IDictionary Links { get; } + public IDictionary? Links { get; } } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSchema.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSchema.cs index b6352311c..bd551a786 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSchema.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSchema.cs @@ -15,43 +15,43 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// /// Follow JSON Schema definition. Short text providing information about the data. /// - public string Title { get; } + public string? Title { get; } /// /// $schema, a JSON Schema dialect identifier. Value must be a URI /// - public Uri Schema { get; } + public Uri? Schema { get; } /// /// $id - Identifies a schema resource with its canonical URI. /// - public string Id { get; } + public string? Id { get; } /// /// $comment - reserves a location for comments from schema authors to readers or maintainers of the schema. /// - public string Comment { get; } + public string? Comment { get; } /// /// $vocabulary- used in meta-schemas to identify the vocabularies available for use in schemas described by that meta-schema. /// - public IDictionary Vocabulary { get; } + public IDictionary? Vocabulary { get; } /// /// $dynamicRef - an applicator that allows for deferring the full resolution until runtime, at which point it is resolved each time it is encountered while evaluating an instance /// - public string DynamicRef { get; } + public string? DynamicRef { get; } /// /// $dynamicAnchor - used to create plain name fragments that are not tied to any particular structural location for referencing purposes, which are taken into consideration for dynamic referencing. /// - public string DynamicAnchor { get; } + public string? DynamicAnchor { get; } /// /// $defs - reserves a location for schema authors to inline re-usable JSON Schemas into a more general schema. /// The keyword does not directly affect the validation result /// - public IDictionary Definitions { get; } + public IDictionary? Definitions { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 @@ -77,14 +77,14 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// /// Follow JSON Schema definition: https://json-schema.org/draft/2020-12/json-schema-validation /// - public string Const { get; } + public string? Const { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 /// While relying on JSON Schema's defined formats, /// the OAS offers a few additional predefined formats. /// - public string Format { get; } + public string? Format { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 @@ -110,7 +110,7 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 /// This string SHOULD be a valid regular expression, according to the ECMA 262 regular expression dialect /// - public string Pattern { get; } + public string? Pattern { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 @@ -123,7 +123,7 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// Unlike JSON Schema, the value MUST conform to the defined type for the Schema Object defined at the same level. /// For example, if type is string, then default can be "foo" but cannot be 1. /// - public JsonNode Default { get; } + public JsonNode? Default { get; } /// /// Relevant only for Schema "properties" definitions. Declares the property as "read only". @@ -149,37 +149,37 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 /// Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. /// - public IList AllOf { get; } + public IList? AllOf { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 /// Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. /// - public IList OneOf { get; } + public IList? OneOf { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 /// Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. /// - public IList AnyOf { get; } + public IList? AnyOf { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 /// Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. /// - public IOpenApiSchema Not { get; } + public IOpenApiSchema? Not { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 /// - public ISet Required { get; } + public ISet? Required { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 /// Value MUST be an object and not an array. Inline or referenced schema MUST be of a Schema Object /// and not a standard JSON Schema. items MUST be present if the type is array. /// - public IOpenApiSchema Items { get; } + public IOpenApiSchema? Items { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 @@ -200,7 +200,7 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 /// Property definitions MUST be a Schema Object and not a standard JSON Schema (inline or referenced). /// - public IDictionary Properties { get; } + public IDictionary? Properties { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 @@ -209,7 +209,7 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// egular expression dialect. Each property value of this object MUST be an object, and each object MUST /// be a valid Schema Object not a standard JSON Schema. /// - public IDictionary PatternProperties { get; } + public IDictionary? PatternProperties { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 @@ -231,32 +231,32 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// Value can be boolean or object. Inline or referenced schema /// MUST be of a Schema Object and not a standard JSON Schema. /// - public IOpenApiSchema AdditionalProperties { get; } + public IOpenApiSchema? AdditionalProperties { get; } /// /// Adds support for polymorphism. The discriminator is an object name that is used to differentiate /// between other schemas which may satisfy the payload description. /// - public OpenApiDiscriminator Discriminator { get; } + public OpenApiDiscriminator? Discriminator { get; } /// /// A free-form property to include an example of an instance for this schema. /// To represent examples that cannot be naturally represented in JSON or YAML, /// a string value can be used to contain the example with escaping where necessary. /// - public JsonNode Example { get; } + public JsonNode? Example { get; } /// /// A free-form property to include examples of an instance for this schema. /// To represent examples that cannot be naturally represented in JSON or YAML, /// a list of values can be used to contain the examples with escaping where necessary. /// - public IList Examples { get; } + public IList? Examples { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 /// - public IList Enum { get; } + public IList? Enum { get; } /// /// Follow JSON Schema definition: https://tools.ietf.org/html/draft-fge-json-schema-validation-00 @@ -266,7 +266,7 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// /// Additional external documentation for this schema. /// - public OpenApiExternalDocs ExternalDocs { get; } + public OpenApiExternalDocs? ExternalDocs { get; } /// /// Specifies that a schema is deprecated and SHOULD be transitioned out of usage. @@ -278,21 +278,21 @@ public interface IOpenApiSchema : IOpenApiDescribedElement, IOpenApiReadOnlyExte /// This MAY be used only on properties schemas. It has no effect on root schemas. /// Adds additional metadata to describe the XML representation of this property. /// - public OpenApiXml Xml { get; } + public OpenApiXml? Xml { get; } /// /// This object stores any unrecognized keywords found in the schema. /// - public IDictionary UnrecognizedKeywords { get; } + public IDictionary? UnrecognizedKeywords { get; } /// /// Any annotation to attach to the schema to be used by the application. /// Annotations are NOT (de)serialized with the schema and can be used for custom properties. /// - public IDictionary Annotations { get; } + public IDictionary? Annotations { get; } /// /// Follow JSON Schema definition:https://json-schema.org/draft/2020-12/json-schema-validation#section-6.5.4 /// - public IDictionary> DependentRequired { get; } + public IDictionary>? DependentRequired { get; } } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSecurityScheme.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSecurityScheme.cs index d076a6896..202337feb 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSecurityScheme.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSecurityScheme.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; @@ -18,7 +18,7 @@ public interface IOpenApiSecurityScheme : IOpenApiDescribedElement, IOpenApiRead /// /// REQUIRED. The name of the header, query or cookie parameter to be used. /// - public string Name { get; } + public string? Name { get; } /// /// REQUIRED. The location of the API key. Valid values are "query", "header" or "cookie". @@ -29,22 +29,22 @@ public interface IOpenApiSecurityScheme : IOpenApiDescribedElement, IOpenApiRead /// REQUIRED. The name of the HTTP Authorization scheme to be used /// in the Authorization header as defined in RFC7235. /// - public string Scheme { get; } + public string? Scheme { get; } /// /// A hint to the client to identify how the bearer token is formatted. /// Bearer tokens are usually generated by an authorization server, /// so this information is primarily for documentation purposes. /// - public string BearerFormat { get; } + public string? BearerFormat { get; } /// /// REQUIRED. An object containing configuration information for the flow types supported. /// - public OpenApiOAuthFlows Flows { get; } + public OpenApiOAuthFlows? Flows { get; } /// /// REQUIRED. OpenId Connect URL to discover OAuth2 configuration values. /// - public Uri OpenIdConnectUrl { get; } + public Uri? OpenIdConnectUrl { get; } } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSummarizedElement.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSummarizedElement.cs index 3273b03f5..e3595bf69 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSummarizedElement.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiSummarizedElement.cs @@ -1,4 +1,4 @@ -using Microsoft.OpenApi.Interfaces; +using Microsoft.OpenApi.Interfaces; namespace Microsoft.OpenApi.Models.Interfaces; /// @@ -9,5 +9,5 @@ public interface IOpenApiSummarizedElement : IOpenApiElement /// /// Short description for the example. /// - public string Summary { get; set; } + public string? Summary { get; set; } } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiTag.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiTag.cs index fdf022413..00a45f4d9 100644 --- a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiTag.cs +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiTag.cs @@ -1,4 +1,4 @@ -using Microsoft.OpenApi.Interfaces; +using Microsoft.OpenApi.Interfaces; namespace Microsoft.OpenApi.Models.Interfaces; @@ -11,10 +11,10 @@ public interface IOpenApiTag : IOpenApiReadOnlyExtensible, IOpenApiReadOnlyDescr /// /// The name of the tag. /// - public string Name { get; } + public string? Name { get; } /// /// Additional external documentation for this tag. /// - public OpenApiExternalDocs ExternalDocs { get; } + public OpenApiExternalDocs? ExternalDocs { get; } } diff --git a/src/Microsoft.OpenApi/Models/OpenApiCallback.cs b/src/Microsoft.OpenApi/Models/OpenApiCallback.cs index 96f5c5cf4..435d9155e 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiCallback.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiCallback.cs @@ -16,14 +16,14 @@ namespace Microsoft.OpenApi.Models public class OpenApiCallback : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiCallback { /// - public Dictionary PathItems { get; set; } + public Dictionary? PathItems { get; set; } = []; /// /// This object MAY be extended with Specification Extensions. /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameter-less constructor @@ -36,7 +36,7 @@ public OpenApiCallback() { } internal OpenApiCallback(IOpenApiCallback callback) { Utils.CheckArgumentNull(callback); - PathItems = callback?.PathItems != null ? new(callback?.PathItems) : null; + PathItems = callback?.PathItems != null ? new(callback.PathItems) : null; Extensions = callback?.Extensions != null ? new Dictionary(callback.Extensions) : null; } @@ -81,9 +81,12 @@ internal void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion versio writer.WriteStartObject(); // path items - foreach (var item in PathItems) + if (PathItems != null) { - writer.WriteRequiredObject(item.Key.Expression, item.Value, callback); + foreach (var item in PathItems) + { + writer.WriteRequiredObject(item.Key.Expression, item.Value, callback); + } } // extensions diff --git a/src/Microsoft.OpenApi/Models/OpenApiContact.cs b/src/Microsoft.OpenApi/Models/OpenApiContact.cs index 15d67cc76..940388887 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiContact.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiContact.cs @@ -16,23 +16,23 @@ public class OpenApiContact : IOpenApiSerializable, IOpenApiExtensible /// /// The identifying name of the contact person/organization. /// - public string Name { get; set; } + public string? Name { get; set; } /// /// The URL pointing to the contact information. MUST be in the format of a URL. /// - public Uri Url { get; set; } + public Uri? Url { get; set; } /// /// The email address of the contact person/organization. /// MUST be in the format of an email address. /// - public string Email { get; set; } + public string? Email { get; set; } /// /// This object MAY be extended with Specification Extensions. /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameter-less constructor diff --git a/src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs b/src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs index 342025f9f..3bbae4561 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDiscriminator.cs @@ -15,17 +15,17 @@ public class OpenApiDiscriminator : IOpenApiSerializable, IOpenApiExtensible /// /// REQUIRED. The name of the property in the payload that will hold the discriminator value. /// - public string PropertyName { get; set; } + public string? PropertyName { get; set; } /// /// An object to hold mappings between payload values and schema names or references. /// - public IDictionary Mapping { get; set; } = new Dictionary(); + public IDictionary? Mapping { get; set; } = new Dictionary(); /// /// This object MAY be extended with Specification Extensions. /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameter-less constructor diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index 3354a6717..0f69409d6 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -132,16 +132,16 @@ public OpenApiDocument() /// public OpenApiDocument(OpenApiDocument? document) { - Workspace = document?.Workspace != null ? new(document?.Workspace) : null; - Info = document?.Info != null ? new(document?.Info) : new OpenApiInfo(); + Workspace = document?.Workspace != null ? new(document.Workspace) : null; + Info = document?.Info != null ? new(document.Info) : new OpenApiInfo(); JsonSchemaDialect = document?.JsonSchemaDialect ?? JsonSchemaDialect; Servers = document?.Servers != null ? new List(document.Servers) : null; - Paths = document?.Paths != null ? new(document?.Paths) : new OpenApiPaths(); + Paths = document?.Paths != null ? new(document.Paths) : new OpenApiPaths(); Webhooks = document?.Webhooks != null ? new Dictionary(document.Webhooks) : null; Components = document?.Components != null ? new(document?.Components) : null; Security = document?.Security != null ? new List(document.Security) : null; Tags = document?.Tags != null ? new HashSet(document.Tags, OpenApiTagComparer.Instance) : null; - ExternalDocs = document?.ExternalDocs != null ? new(document?.ExternalDocs) : null; + ExternalDocs = document?.ExternalDocs != null ? new(document.ExternalDocs) : null; Extensions = document?.Extensions != null ? new Dictionary(document.Extensions) : null; Metadata = document?.Metadata != null ? new Dictionary(document.Metadata) : null; BaseUri = document?.BaseUri != null ? document.BaseUri : new(OpenApiConstants.BaseRegistryUri + Guid.NewGuid()); @@ -294,12 +294,19 @@ public void SerializeAsV2(IOpenApiWriter writer) if (loops.TryGetValue(typeof(IOpenApiSchema), out var schemas)) { - var openApiSchemas = schemas.Cast().Distinct().OfType() - .ToDictionary(k => k.Reference.Id, v => v); + var openApiSchemas = schemas.Cast() + .Distinct() + .OfType() + .Where(k => k.Reference?.Id is not null) + .ToDictionary( + k => k.Reference?.Id!, + v => v + ); + foreach (var schema in openApiSchemas.Values.ToList()) { - FindSchemaReferences.ResolveSchemas(Components, openApiSchemas); + FindSchemaReferences.ResolveSchemas(Components, openApiSchemas!); } writer.WriteOptionalMap( @@ -337,7 +344,9 @@ public void SerializeAsV2(IOpenApiWriter writer) { foreach (var requestBody in Components.RequestBodies.Where(b => !parameters.ContainsKey(b.Key))) { - parameters.Add(requestBody.Key, requestBody.Value.ConvertToBodyParameter(writer)); + var paramValue = requestBody.Value.ConvertToBodyParameter(writer); + if (paramValue is not null) + parameters.Add(requestBody.Key, paramValue); } } writer.WriteOptionalMap( @@ -406,7 +415,7 @@ public void SerializeAsV2(IOpenApiWriter writer) } } - private static string ParseServerUrl(OpenApiServer server) + private static string? ParseServerUrl(OpenApiServer server) { return server.ReplaceServerUrlVariables(new Dictionary(0)); } @@ -422,61 +431,70 @@ private static void WriteHostInfoV2(IOpenApiWriter writer, IList? // one host, port, and base path. var serverUrl = ParseServerUrl(servers[0]); - // Divide the URL in the Url property into host and basePath required in OpenAPI V2 - // The Url property cannot contain path templating to be valid for V2 serialization. - var firstServerUrl = new Uri(serverUrl, UriKind.RelativeOrAbsolute); - - // host - if (firstServerUrl.IsAbsoluteUri) + if (serverUrl != null) { - writer.WriteProperty( - OpenApiConstants.Host, - firstServerUrl.GetComponents(UriComponents.Host | UriComponents.Port, UriFormat.SafeUnescaped)); + // Divide the URL in the Url property into host and basePath required in OpenAPI V2 + // The Url property cannot contain path templating to be valid for V2 serialization. + var firstServerUrl = new Uri(serverUrl, UriKind.RelativeOrAbsolute); - // basePath - if (firstServerUrl.AbsolutePath != "/") - { - writer.WriteProperty(OpenApiConstants.BasePath, firstServerUrl.AbsolutePath); - } - } - else - { - var relativeUrl = firstServerUrl.OriginalString; - if (relativeUrl.StartsWith("//", StringComparison.OrdinalIgnoreCase)) + // host + if (firstServerUrl.IsAbsoluteUri) { - var pathPosition = relativeUrl.IndexOf('/', 3); - writer.WriteProperty(OpenApiConstants.Host, relativeUrl.Substring(0, pathPosition)); - relativeUrl = relativeUrl.Substring(pathPosition); + writer.WriteProperty( + OpenApiConstants.Host, + firstServerUrl.GetComponents(UriComponents.Host | UriComponents.Port, UriFormat.SafeUnescaped)); + + // basePath + if (firstServerUrl.AbsolutePath != "/") + { + writer.WriteProperty(OpenApiConstants.BasePath, firstServerUrl.AbsolutePath); + } } - if (!String.IsNullOrEmpty(relativeUrl) && relativeUrl != "/") + else { - writer.WriteProperty(OpenApiConstants.BasePath, relativeUrl); + var relativeUrl = firstServerUrl.OriginalString; + if (relativeUrl.StartsWith("//", StringComparison.OrdinalIgnoreCase)) + { + var pathPosition = relativeUrl.IndexOf('/', 3); + writer.WriteProperty(OpenApiConstants.Host, relativeUrl.Substring(0, pathPosition)); + relativeUrl = relativeUrl.Substring(pathPosition); + } + if (!String.IsNullOrEmpty(relativeUrl) && relativeUrl != "/") + { + writer.WriteProperty(OpenApiConstants.BasePath, relativeUrl); + } } - } - // Consider all schemes of the URLs in the server list that have the same - // host, port, and base path as the first server. - var schemes = servers.Select( - s => + // Consider all schemes of the URLs in the server list that have the same + // host, port, and base path as the first server. + var schemes = servers.Select( + s => + { + Uri.TryCreate(ParseServerUrl(s), UriKind.RelativeOrAbsolute, out var url); + return url; + }) + .Where( + u => u is not null && + Uri.Compare( + u, + firstServerUrl, + UriComponents.Host | UriComponents.Port | UriComponents.Path, + UriFormat.SafeUnescaped, + StringComparison.OrdinalIgnoreCase) == + 0 && u.IsAbsoluteUri) + .Select(u => u!.Scheme) + .Distinct() + .ToList(); + + // schemes + writer.WriteOptionalCollection(OpenApiConstants.Schemes, schemes, (w, s) => + { + if(!string.IsNullOrEmpty(s) && s is not null) { - Uri.TryCreate(ParseServerUrl(s), UriKind.RelativeOrAbsolute, out var url); - return url; - }) - .Where( - u => u is not null && - Uri.Compare( - u, - firstServerUrl, - UriComponents.Host | UriComponents.Port | UriComponents.Path, - UriFormat.SafeUnescaped, - StringComparison.OrdinalIgnoreCase) == - 0 && u.IsAbsoluteUri) - .Select(u => u!.Scheme) - .Distinct() - .ToList(); - - // schemes - writer.WriteOptionalCollection(OpenApiConstants.Schemes, schemes, (w, s) => w.WriteValue(s)); + w.WriteValue(s); + } + }); + } } /// @@ -548,19 +566,15 @@ private static string ConvertByteArrayToString(byte[] hash) return null; } - if (!reference.Type.HasValue) - { - throw new ArgumentException(Properties.SRResource.LocalReferenceRequiresType); - } - string uriLocation; - if (reference.Id.Contains("/")) // this means its a URL reference + var id = reference.Id; + if (!string.IsNullOrEmpty(id) && id!.Contains("/")) // this means its a URL reference { - uriLocation = reference.Id; + uriLocation = id; } else { - string relativePath = OpenApiConstants.ComponentsSegment + reference.Type.GetDisplayName() + "/" + reference.Id; + string relativePath = OpenApiConstants.ComponentsSegment + reference.Type.GetDisplayName() + "/" + id; uriLocation = useExternal ? Workspace?.GetDocumentId(reference.ExternalResource)?.OriginalString + relativePath @@ -704,9 +718,10 @@ public override void Visit(IOpenApiReferenceHolder referenceHolder) switch (referenceHolder) { case OpenApiSchemaReference schema: - if (!Schemas.ContainsKey(schema.Reference.Id)) + var id = schema.Reference?.Id; + if (id is not null && Schemas is not null && !Schemas.ContainsKey(id)) { - Schemas.Add(schema.Reference.Id, schema); + Schemas.Add(id, schema); } break; @@ -719,10 +734,14 @@ public override void Visit(IOpenApiReferenceHolder referenceHolder) public override void Visit(IOpenApiSchema schema) { // This is needed to handle schemas used in Responses in components - if (schema is OpenApiSchemaReference {Reference: not null} schemaReference && !Schemas.ContainsKey(schemaReference.Reference.Id)) + if (schema is OpenApiSchemaReference { Reference: not null } schemaReference) { - Schemas.Add(schemaReference.Reference.Id, schema); - } + var id = schemaReference.Reference?.Id; + if (id is not null && Schemas is not null && !Schemas.ContainsKey(id)) + { + Schemas.Add(id, schema); + } + } base.Visit(schema); } } diff --git a/src/Microsoft.OpenApi/Models/OpenApiEncoding.cs b/src/Microsoft.OpenApi/Models/OpenApiEncoding.cs index bb8bfab17..4eae8e6ce 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiEncoding.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiEncoding.cs @@ -20,12 +20,12 @@ public class OpenApiEncoding : IOpenApiSerializable, IOpenApiExtensible /// The value can be a specific media type (e.g. application/json), /// a wildcard media type (e.g. image/*), or a comma-separated list of the two types. /// - public string ContentType { get; set; } + public string? ContentType { get; set; } /// /// A map allowing additional information to be provided as headers. /// - public IDictionary Headers { get; set; } = new Dictionary(); + public IDictionary? Headers { get; set; } = new Dictionary(); /// /// Describes how a specific property value will be serialized depending on its type. @@ -52,7 +52,7 @@ public class OpenApiEncoding : IOpenApiSerializable, IOpenApiExtensible /// /// This object MAY be extended with Specification Extensions. /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameter-less constructor diff --git a/src/Microsoft.OpenApi/Models/OpenApiError.cs b/src/Microsoft.OpenApi/Models/OpenApiError.cs index 54b98a067..8a42cb38a 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiError.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiError.cs @@ -20,7 +20,7 @@ public OpenApiError(OpenApiException exception) : this(exception.Pointer, except /// /// Initializes the class. /// - public OpenApiError(string pointer, string message) + public OpenApiError(string? pointer, string message) { Pointer = pointer; Message = message; @@ -43,7 +43,7 @@ public OpenApiError(OpenApiError error) /// /// Pointer to the location of the error. /// - public string Pointer { get; set; } + public string? Pointer { get; set; } /// /// Gets the string representation of . diff --git a/src/Microsoft.OpenApi/Models/OpenApiExample.cs b/src/Microsoft.OpenApi/Models/OpenApiExample.cs index bdfd42f4e..1470ca51a 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiExample.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiExample.cs @@ -16,19 +16,19 @@ namespace Microsoft.OpenApi.Models public class OpenApiExample : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiExample { /// - public string Summary { get; set; } + public string? Summary { get; set; } /// - public string Description { get; set; } + public string? Description { get; set; } /// - public string ExternalValue { get; set; } + public string? ExternalValue { get; set; } /// - public JsonNode Value { get; set; } + public JsonNode? Value { get; set; } /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameter-less constructor diff --git a/src/Microsoft.OpenApi/Models/OpenApiExtensibleDictionary.cs b/src/Microsoft.OpenApi/Models/OpenApiExtensibleDictionary.cs index 86fe7ea73..e9b07bf58 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiExtensibleDictionary.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiExtensibleDictionary.cs @@ -20,7 +20,7 @@ public abstract class OpenApiExtensibleDictionary : Dictionary, /// /// Parameterless constructor /// - protected OpenApiExtensibleDictionary():this(null) { } + protected OpenApiExtensibleDictionary():this([]) { } /// /// Initializes a copy of class. /// @@ -28,7 +28,7 @@ protected OpenApiExtensibleDictionary():this(null) { } /// The dictionary of . protected OpenApiExtensibleDictionary( Dictionary dictionary, - IDictionary extensions = null) : base(dictionary is null ? [] : dictionary) + IDictionary? extensions = null) : base(dictionary is null ? [] : dictionary) { Extensions = extensions != null ? new Dictionary(extensions) : []; } @@ -36,7 +36,7 @@ protected OpenApiExtensibleDictionary( /// /// This object MAY be extended with Specification Extensions. /// - public IDictionary Extensions { get; set; } + public IDictionary? Extensions { get; set; } /// diff --git a/src/Microsoft.OpenApi/Models/OpenApiExternalDocs.cs b/src/Microsoft.OpenApi/Models/OpenApiExternalDocs.cs index cceace01d..2694aa26a 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiExternalDocs.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiExternalDocs.cs @@ -16,17 +16,17 @@ public class OpenApiExternalDocs : IOpenApiSerializable, IOpenApiExtensible /// /// A short description of the target documentation. /// - public string Description { get; set; } + public string? Description { get; set; } /// /// REQUIRED. The URL for the target documentation. Value MUST be in the format of a URL. /// - public Uri Url { get; set; } + public Uri? Url { get; set; } /// /// This object MAY be extended with Specification Extensions. /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameter-less constructor @@ -69,7 +69,7 @@ public void SerializeAsV2(IOpenApiWriter writer) private void WriteInternal(IOpenApiWriter writer, OpenApiSpecVersion specVersion) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); writer.WriteStartObject(); diff --git a/src/Microsoft.OpenApi/Models/OpenApiHeader.cs b/src/Microsoft.OpenApi/Models/OpenApiHeader.cs index 08dd04b99..82d17aece 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiHeader.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiHeader.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; @@ -20,7 +20,7 @@ namespace Microsoft.OpenApi.Models public class OpenApiHeader : IOpenApiHeader, IOpenApiExtensible { /// - public string Description { get; set; } + public string? Description { get; set; } /// public bool Required { get; set; } @@ -41,19 +41,19 @@ public class OpenApiHeader : IOpenApiHeader, IOpenApiExtensible public bool AllowReserved { get; set; } /// - public IOpenApiSchema Schema { get; set; } + public IOpenApiSchema? Schema { get; set; } /// - public JsonNode Example { get; set; } + public JsonNode? Example { get; set; } /// - public IDictionary Examples { get; set; } = new Dictionary(); + public IDictionary? Examples { get; set; } = new Dictionary(); /// - public IDictionary Content { get; set; } = new Dictionary(); + public IDictionary? Content { get; set; } = new Dictionary(); /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameter-less constructor @@ -73,7 +73,7 @@ internal OpenApiHeader(IOpenApiHeader header) Style = header.Style ?? Style; Explode = header.Explode; AllowReserved = header.AllowReserved; - Schema = header.Schema.CreateShallowCopy(); + Schema = header.Schema?.CreateShallowCopy(); Example = header.Example != null ? JsonNodeCloneHelper.Clone(header.Example) : null; Examples = header.Examples != null ? new Dictionary(header.Examples) : null; Content = header.Content != null ? new Dictionary(header.Content) : null; diff --git a/src/Microsoft.OpenApi/Models/OpenApiInfo.cs b/src/Microsoft.OpenApi/Models/OpenApiInfo.cs index 68e37ee20..93e89438c 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiInfo.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiInfo.cs @@ -16,42 +16,42 @@ public class OpenApiInfo : IOpenApiSerializable, IOpenApiExtensible /// /// REQUIRED. The title of the application. /// - public string Title { get; set; } + public string? Title { get; set; } /// /// A short summary of the API. /// - public string Summary { get; set; } + public string? Summary { get; set; } /// /// A short description of the application. /// - public string Description { get; set; } + public string? Description { get; set; } /// /// REQUIRED. The version of the OpenAPI document. /// - public string Version { get; set; } + public string? Version { get; set; } /// /// A URL to the Terms of Service for the API. MUST be in the format of a URL. /// - public Uri TermsOfService { get; set; } + public Uri? TermsOfService { get; set; } /// /// The contact information for the exposed API. /// - public OpenApiContact Contact { get; set; } + public OpenApiContact? Contact { get; set; } /// /// The license information for the exposed API. /// - public OpenApiLicense License { get; set; } + public OpenApiLicense? License { get; set; } /// /// This object MAY be extended with Specification Extensions. /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameter-less constructor @@ -68,8 +68,8 @@ public OpenApiInfo(OpenApiInfo info) Description = info?.Description ?? Description; Version = info?.Version ?? Version; TermsOfService = info?.TermsOfService ?? TermsOfService; - Contact = info?.Contact != null ? new(info?.Contact) : null; - License = info?.License != null ? new(info?.License) : null; + Contact = info?.Contact != null ? new(info.Contact) : null; + License = info?.License != null ? new(info.License) : null; Extensions = info?.Extensions != null ? new Dictionary(info.Extensions) : null; } @@ -100,7 +100,7 @@ public void SerializeAsV3(IOpenApiWriter writer) /// private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, Action callback) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); writer.WriteStartObject(); // title @@ -130,7 +130,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version /// public void SerializeAsV2(IOpenApiWriter writer) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); writer.WriteStartObject(); diff --git a/src/Microsoft.OpenApi/Models/OpenApiLicense.cs b/src/Microsoft.OpenApi/Models/OpenApiLicense.cs index 6a8d4bcf7..8aea264e6 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiLicense.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiLicense.cs @@ -16,22 +16,22 @@ public class OpenApiLicense : IOpenApiSerializable, IOpenApiExtensible /// /// REQUIRED. The license name used for the API. /// - public string Name { get; set; } + public string? Name { get; set; } /// /// An SPDX license expression for the API. The identifier field is mutually exclusive of the url field. /// - public string Identifier { get; set; } + public string? Identifier { get; set; } /// /// The URL pointing to the contact information. MUST be in the format of a URL. /// - public Uri Url { get; set; } + public Uri? Url { get; set; } /// /// This object MAY be extended with Specification Extensions. /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameterless constructor @@ -79,7 +79,7 @@ public void SerializeAsV2(IOpenApiWriter writer) private void WriteInternal(IOpenApiWriter writer, OpenApiSpecVersion specVersion) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); writer.WriteStartObject(); // name diff --git a/src/Microsoft.OpenApi/Models/OpenApiLink.cs b/src/Microsoft.OpenApi/Models/OpenApiLink.cs index 09883b4a2..412577580 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiLink.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiLink.cs @@ -15,25 +15,25 @@ namespace Microsoft.OpenApi.Models public class OpenApiLink : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiLink { /// - public string OperationRef { get; set; } + public string? OperationRef { get; set; } /// - public string OperationId { get; set; } + public string? OperationId { get; set; } /// - public IDictionary Parameters { get; set; } = new Dictionary(); + public IDictionary? Parameters { get; set; } = new Dictionary(); /// - public RuntimeExpressionAnyWrapper RequestBody { get; set; } + public RuntimeExpressionAnyWrapper? RequestBody { get; set; } /// - public string Description { get; set; } + public string? Description { get; set; } /// - public OpenApiServer Server { get; set; } + public OpenApiServer? Server { get; set; } /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameterless constructor diff --git a/src/Microsoft.OpenApi/Models/OpenApiOAuthFlow.cs b/src/Microsoft.OpenApi/Models/OpenApiOAuthFlow.cs index 2385a4c55..d84417cef 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiOAuthFlow.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiOAuthFlow.cs @@ -17,28 +17,28 @@ public class OpenApiOAuthFlow : IOpenApiSerializable, IOpenApiExtensible /// REQUIRED. The authorization URL to be used for this flow. /// Applies to implicit and authorizationCode OAuthFlow. /// - public Uri AuthorizationUrl { get; set; } + public Uri? AuthorizationUrl { get; set; } /// /// REQUIRED. The token URL to be used for this flow. /// Applies to password, clientCredentials, and authorizationCode OAuthFlow. /// - public Uri TokenUrl { get; set; } + public Uri? TokenUrl { get; set; } /// /// The URL to be used for obtaining refresh tokens. /// - public Uri RefreshUrl { get; set; } + public Uri? RefreshUrl { get; set; } /// /// REQUIRED. A map between the scope name and a short description for it. /// - public IDictionary Scopes { get; set; } = new Dictionary(); + public IDictionary? Scopes { get; set; } = new Dictionary(); /// /// Specification Extensions. /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameterless constructor @@ -78,7 +78,7 @@ public void SerializeAsV3(IOpenApiWriter writer) /// private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); writer.WriteStartObject(); diff --git a/src/Microsoft.OpenApi/Models/OpenApiOAuthFlows.cs b/src/Microsoft.OpenApi/Models/OpenApiOAuthFlows.cs index 5211159a4..758e1e02d 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiOAuthFlows.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiOAuthFlows.cs @@ -16,27 +16,27 @@ public class OpenApiOAuthFlows : IOpenApiSerializable, IOpenApiExtensible /// /// Configuration for the OAuth Implicit flow /// - public OpenApiOAuthFlow Implicit { get; set; } + public OpenApiOAuthFlow? Implicit { get; set; } /// /// Configuration for the OAuth Resource Owner Password flow. /// - public OpenApiOAuthFlow Password { get; set; } + public OpenApiOAuthFlow? Password { get; set; } /// /// Configuration for the OAuth Client Credentials flow. /// - public OpenApiOAuthFlow ClientCredentials { get; set; } + public OpenApiOAuthFlow? ClientCredentials { get; set; } /// /// Configuration for the OAuth Authorization Code flow. /// - public OpenApiOAuthFlow AuthorizationCode { get; set; } + public OpenApiOAuthFlow? AuthorizationCode { get; set; } /// /// Specification Extensions. /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameterless constructor @@ -49,10 +49,10 @@ public OpenApiOAuthFlows() { } /// public OpenApiOAuthFlows(OpenApiOAuthFlows oAuthFlows) { - Implicit = oAuthFlows?.Implicit != null ? new(oAuthFlows?.Implicit) : null; - Password = oAuthFlows?.Password != null ? new(oAuthFlows?.Password) : null; - ClientCredentials = oAuthFlows?.ClientCredentials != null ? new(oAuthFlows?.ClientCredentials) : null; - AuthorizationCode = oAuthFlows?.AuthorizationCode != null ? new(oAuthFlows?.AuthorizationCode) : null; + Implicit = oAuthFlows?.Implicit != null ? new(oAuthFlows.Implicit) : null; + Password = oAuthFlows?.Password != null ? new(oAuthFlows.Password) : null; + ClientCredentials = oAuthFlows?.ClientCredentials != null ? new(oAuthFlows.ClientCredentials) : null; + AuthorizationCode = oAuthFlows?.AuthorizationCode != null ? new(oAuthFlows.AuthorizationCode) : null; Extensions = oAuthFlows?.Extensions != null ? new Dictionary(oAuthFlows.Extensions) : null; } @@ -78,7 +78,7 @@ public void SerializeAsV3(IOpenApiWriter writer) private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, Action callback) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); writer.WriteStartObject(); diff --git a/src/Microsoft.OpenApi/Models/OpenApiOperation.cs b/src/Microsoft.OpenApi/Models/OpenApiOperation.cs index 2ea920640..5375fb031 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiOperation.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiOperation.cs @@ -262,17 +262,18 @@ public void SerializeAsV2(IOpenApiWriter writer) if (consumes.Count > 0) { // This is form data. We need to split the request body into multiple parameters. - if (consumes.Contains("application/x-www-form-urlencoded") || - consumes.Contains("multipart/form-data")) + if ((consumes.Contains("application/x-www-form-urlencoded") || + consumes.Contains("multipart/form-data")) && + RequestBody.ConvertToFormDataParameters(writer) is { } formDataParameters) { - parameters.AddRange(RequestBody.ConvertToFormDataParameters(writer)); + parameters.AddRange(formDataParameters); } - else + else if (RequestBody.ConvertToBodyParameter(writer) is { } bodyParameter) { - parameters.Add(RequestBody.ConvertToBodyParameter(writer)); + parameters.Add(bodyParameter); } } - else if (RequestBody is OpenApiRequestBodyReference requestBodyReference) + else if (RequestBody is OpenApiRequestBodyReference requestBodyReference && requestBodyReference.Reference.Id is not null) { parameters.Add( new OpenApiParameterReference(requestBodyReference.Reference.Id, requestBodyReference.Reference.HostDocument)); @@ -336,7 +337,13 @@ public void SerializeAsV2(IOpenApiWriter writer) .Distinct() .ToList(); - writer.WriteOptionalCollection(OpenApiConstants.Schemes, schemes, (w, s) => w.WriteValue(s)); + writer.WriteOptionalCollection(OpenApiConstants.Schemes, schemes, (w, s) => + { + if (!string.IsNullOrEmpty(s) && s is not null) + { + w.WriteValue(s); + } + }); } // deprecated diff --git a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs index da299e4b5..652e65b3d 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs @@ -23,13 +23,13 @@ public class OpenApiParameter : IOpenApiExtensible, IOpenApiParameter private ParameterStyle? _style; /// - public string Name { get; set; } + public string? Name { get; set; } /// public ParameterLocation? In { get; set; } /// - public string Description { get; set; } + public string? Description { get; set; } /// public bool Required { get; set; } @@ -58,19 +58,19 @@ public bool Explode public bool AllowReserved { get; set; } /// - public IOpenApiSchema Schema { get; set; } + public IOpenApiSchema? Schema { get; set; } /// - public IDictionary Examples { get; set; } = new Dictionary(); + public IDictionary? Examples { get; set; } = new Dictionary(); /// - public JsonNode Example { get; set; } + public JsonNode? Example { get; set; } /// - public IDictionary Content { get; set; } = new Dictionary(); + public IDictionary? Content { get; set; } = new Dictionary(); /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// A parameterless constructor @@ -90,7 +90,7 @@ internal OpenApiParameter(IOpenApiParameter parameter) Style = parameter.Style ?? Style; Explode = parameter.Explode; AllowReserved = parameter.AllowReserved; - Schema = parameter.Schema.CreateShallowCopy(); + Schema = parameter.Schema?.CreateShallowCopy(); Examples = parameter.Examples != null ? new Dictionary(parameter.Examples) : null; Example = parameter.Example != null ? JsonNodeCloneHelper.Clone(parameter.Example) : null; Content = parameter.Content != null ? new Dictionary(parameter.Content) : null; @@ -199,7 +199,7 @@ public void SerializeAsV2(IOpenApiWriter writer) // deprecated writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false); - var extensionsClone = new Dictionary(Extensions); + var extensionsClone = Extensions is not null ? new Dictionary(Extensions) : null; // schema if (this is OpenApiBodyParameter) @@ -239,14 +239,14 @@ public void SerializeAsV2(IOpenApiWriter writer) if (targetSchema is not null) { targetSchema.WriteAsItemsProperties(writer); - var extensions = Schema.Extensions; + var extensions = Schema?.Extensions; if (extensions != null) { foreach (var key in extensions.Keys) { // The extension will already have been serialized as part of the call to WriteAsItemsProperties above, // so remove it from the cloned collection so we don't write it again. - extensionsClone.Remove(key); + extensionsClone?.Remove(key); } } } diff --git a/src/Microsoft.OpenApi/Models/OpenApiPathItem.cs b/src/Microsoft.OpenApi/Models/OpenApiPathItem.cs index 1d4be44ad..6e89d9684 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiPathItem.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiPathItem.cs @@ -17,23 +17,23 @@ namespace Microsoft.OpenApi.Models public class OpenApiPathItem : IOpenApiExtensible, IOpenApiReferenceable, IOpenApiPathItem { /// - public string Summary { get; set; } + public string? Summary { get; set; } /// - public string Description { get; set; } + public string? Description { get; set; } /// - public IDictionary Operations { get; set; } + public IDictionary? Operations { get; set; } = new Dictionary(); /// - public IList Servers { get; set; } = []; + public IList? Servers { get; set; } = []; /// - public IList Parameters { get; set; } = []; + public IList? Parameters { get; set; } = []; /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Add one operation into this path item. @@ -42,7 +42,10 @@ public class OpenApiPathItem : IOpenApiExtensible, IOpenApiReferenceable, IOpenA /// The operation item. public void AddOperation(HttpMethod operationType, OpenApiOperation operation) { - Operations[operationType] = operation; + if (Operations is not null) + { + Operations[operationType] = operation; + } } /// @@ -91,14 +94,17 @@ public void SerializeAsV2(IOpenApiWriter writer) writer.WriteStartObject(); // operations except "trace" - foreach (var operation in Operations) + if (Operations != null) { - if (operation.Key != HttpMethod.Trace) + foreach (var operation in Operations) { - writer.WriteOptionalObject( - operation.Key.Method.ToLowerInvariant(), - operation.Value, - (w, o) => o.SerializeAsV2(w)); + if (operation.Key != HttpMethod.Trace) + { + writer.WriteOptionalObject( + operation.Key.Method.ToLowerInvariant(), + operation.Value, + (w, o) => o.SerializeAsV2(w)); + } } } @@ -133,12 +139,15 @@ internal virtual void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersio writer.WriteProperty(OpenApiConstants.Description, Description); // operations - foreach (var operation in Operations) + if (Operations != null) { - writer.WriteOptionalObject( + foreach (var operation in Operations) + { + writer.WriteOptionalObject( operation.Key.Method.ToLowerInvariant(), operation.Value, callback); + } } // servers diff --git a/src/Microsoft.OpenApi/Models/OpenApiReference.cs b/src/Microsoft.OpenApi/Models/OpenApiReference.cs index 00d992a9e..ae79cc10f 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiReference.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiReference.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; @@ -20,14 +20,14 @@ public class OpenApiReference : IOpenApiSerializable, IOpenApiDescribedElement, /// A short summary which by default SHOULD override that of the referenced component. /// If the referenced object-type does not allow a summary field, then this field has no effect. /// - public string Summary { get; set; } + public string? Summary { get; set; } /// /// A description which by default SHOULD override that of the referenced component. /// CommonMark syntax MAY be used for rich text representation. /// If the referenced object-type does not allow a description field, then this field has no effect. /// - public string Description { get; set; } + public string? Description { get; set; } /// /// External resource in the reference. @@ -35,13 +35,13 @@ public class OpenApiReference : IOpenApiSerializable, IOpenApiDescribedElement, /// 1. a absolute/relative file path, for example: ../commons/pet.json /// 2. a Url, for example: http://localhost/pet.json /// - public string ExternalResource { get; init; } - + public string? ExternalResource { get; init; } + /// /// The element type referenced. /// /// This must be present if is not present. - public ReferenceType? Type { get; init; } + public ReferenceType Type { get; init; } /// /// The identifier of the reusable component of one particular ReferenceType. @@ -50,7 +50,7 @@ public class OpenApiReference : IOpenApiSerializable, IOpenApiDescribedElement, /// If ExternalResource is not present, this is the name of the component without the reference type name. /// For example, if the reference is '#/components/schemas/componentName', the Id is 'componentName'. /// - public string Id { get; init; } + public string? Id { get; init; } /// /// Gets a flag indicating whether this reference is an external reference. @@ -67,16 +67,16 @@ public class OpenApiReference : IOpenApiSerializable, IOpenApiDescribedElement, /// public bool IsFragment { get; init; } - private OpenApiDocument hostDocument; + private OpenApiDocument? hostDocument; /// /// The OpenApiDocument that is hosting the OpenApiReference instance. This is used to enable dereferencing the reference. /// - public OpenApiDocument HostDocument { get => hostDocument; init => hostDocument = value; } + public OpenApiDocument? HostDocument { get => hostDocument; init => hostDocument = value; } /// /// Gets the full reference string for v3.0. /// - public string ReferenceV3 + public string? ReferenceV3 { get { @@ -85,11 +85,6 @@ public string ReferenceV3 return GetExternalReferenceV3(); } - if (!Type.HasValue) - { - throw new ArgumentNullException(nameof(Type)); - } - if (Type == ReferenceType.Tag) { return Id; @@ -99,20 +94,20 @@ public string ReferenceV3 { return Id; } - if (Id.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || - Id.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) + if (!string.IsNullOrEmpty(Id) && Id is not null && Id.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || + !string.IsNullOrEmpty(Id) && Id is not null && Id.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { return Id; } - return "#/components/" + Type.Value.GetDisplayName() + "/" + Id; + return "#/components/" + Type.GetDisplayName() + "/" + Id; } } /// /// Gets the full reference string for V2.0 /// - public string ReferenceV2 + public string? ReferenceV2 { get { @@ -121,11 +116,6 @@ public string ReferenceV2 return GetExternalReferenceV2(); } - if (!Type.HasValue) - { - throw new ArgumentNullException(nameof(Type)); - } - if (Type == ReferenceType.Tag) { return Id; @@ -136,7 +126,7 @@ public string ReferenceV2 return Id; } - return "#/" + GetReferenceTypeNameAsV2(Type.Value) + "/" + Id; + return "#/" + GetReferenceTypeNameAsV2(Type) + "/" + Id; } } @@ -183,11 +173,11 @@ public void SerializeAsV3(IOpenApiWriter writer) /// /// Serialize /// - private void SerializeInternal(IOpenApiWriter writer, Action callback = null) + private void SerializeInternal(IOpenApiWriter writer, Action? callback = null) { Utils.CheckArgumentNull(writer); - if (Type == ReferenceType.Tag) + if (Type == ReferenceType.Tag && !string.IsNullOrEmpty(ReferenceV3) && ReferenceV3 is not null) { // Write the string value only writer.WriteValue(ReferenceV3); @@ -213,14 +203,14 @@ public void SerializeAsV2(IOpenApiWriter writer) { Utils.CheckArgumentNull(writer); - if (Type == ReferenceType.Tag) + if (Type == ReferenceType.Tag && !string.IsNullOrEmpty(ReferenceV2) && ReferenceV2 is not null) { // Write the string value only writer.WriteValue(ReferenceV2); return; } - if (Type == ReferenceType.SecurityScheme) + if (Type == ReferenceType.SecurityScheme && !string.IsNullOrEmpty(ReferenceV2) && ReferenceV2 is not null) { // Write the string as property name writer.WritePropertyName(ReferenceV2); @@ -235,7 +225,7 @@ public void SerializeAsV2(IOpenApiWriter writer) writer.WriteEndObject(); } - private string GetExternalReferenceV3() + private string? GetExternalReferenceV3() { if (Id != null) { @@ -250,26 +240,23 @@ private string GetExternalReferenceV3() return Id; } - if (Type.HasValue) - { - return ExternalResource + "#/components/" + Type.Value.GetDisplayName() + "/"+ Id; - } + return ExternalResource + "#/components/" + Type.GetDisplayName() + "/"+ Id; } return ExternalResource; } - private string GetExternalReferenceV2() + private string? GetExternalReferenceV2() { - if (Id != null) + if (Id is not null) { - return ExternalResource + "#/" + GetReferenceTypeNameAsV2((ReferenceType)Type) + "/" + Id; + return ExternalResource + "#/" + GetReferenceTypeNameAsV2(Type) + "/" + Id; } return ExternalResource; } - private string GetReferenceTypeNameAsV2(ReferenceType type) + private static string? GetReferenceTypeNameAsV2(ReferenceType type) { return type switch { diff --git a/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs b/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs index 95f86dba3..70d1a1309 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs @@ -19,16 +19,16 @@ namespace Microsoft.OpenApi.Models public class OpenApiRequestBody : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiRequestBody { /// - public string Description { get; set; } + public string? Description { get; set; } /// public bool Required { get; set; } /// - public IDictionary Content { get; set; } = new Dictionary(); + public IDictionary? Content { get; set; } = new Dictionary(); /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameter-less constructor @@ -102,15 +102,17 @@ public IOpenApiParameter ConvertToBodyParameter(IOpenApiWriter writer) // V2 spec actually allows the body to have custom name. // To allow round-tripping we use an extension to hold the name Name = "body", - Schema = Content.Values.FirstOrDefault()?.Schema ?? new OpenApiSchema(), - Examples = Content.Values.FirstOrDefault()?.Examples, + Schema = Content?.Values.FirstOrDefault()?.Schema ?? new OpenApiSchema(), + Examples = Content?.Values.FirstOrDefault()?.Examples, Required = Required, - Extensions = Extensions.ToDictionary(static k => k.Key, static v => v.Value) // Clone extensions so we can remove the x-bodyName extensions from the output V2 model. + Extensions = Extensions?.ToDictionary(static k => k.Key, static v => v.Value) }; - if (bodyParameter.Extensions.ContainsKey(OpenApiConstants.BodyName)) + // Clone extensions so we can remove the x-bodyName extensions from the output V2 model. + if (bodyParameter.Extensions is not null && + bodyParameter.Extensions.TryGetValue(OpenApiConstants.BodyName, out var bodyNameExtension) && + bodyNameExtension is OpenApiAny bodyName) { - var bodyName = bodyParameter.Extensions[OpenApiConstants.BodyName] as OpenApiAny; - bodyParameter.Name = string.IsNullOrEmpty(bodyName?.Node.ToString()) ? "body" : bodyName?.Node.ToString(); + bodyParameter.Name = string.IsNullOrEmpty(bodyName.Node.ToString()) ? "body" : bodyName.Node.ToString(); bodyParameter.Extensions.Remove(OpenApiConstants.BodyName); } return bodyParameter; @@ -121,34 +123,41 @@ public IEnumerable ConvertToFormDataParameters(IOpenApiWriter { if (Content == null || !Content.Any()) yield break; - - foreach (var property in Content.First().Value.Schema.Properties) + var properties = Content.First().Value.Schema?.Properties; + if(properties != null) { - var paramSchema = property.Value.CreateShallowCopy(); - if ((paramSchema.Type & JsonSchemaType.String) == JsonSchemaType.String - && ("binary".Equals(paramSchema.Format, StringComparison.OrdinalIgnoreCase) - || "base64".Equals(paramSchema.Format, StringComparison.OrdinalIgnoreCase))) + foreach (var property in properties) { - var updatedSchema = paramSchema switch { - OpenApiSchema s => s, // we already have a copy - // we have a copy of a reference but don't want to mutate the source schema - // TODO might need recursive resolution of references here - OpenApiSchemaReference r => (OpenApiSchema)r.Target.CreateShallowCopy(), - _ => throw new InvalidOperationException("Unexpected schema type") + var paramSchema = property.Value.CreateShallowCopy(); + if ((paramSchema.Type & JsonSchemaType.String) == JsonSchemaType.String + && ("binary".Equals(paramSchema.Format, StringComparison.OrdinalIgnoreCase) + || "base64".Equals(paramSchema.Format, StringComparison.OrdinalIgnoreCase))) + { + var updatedSchema = paramSchema switch + { + OpenApiSchema s => s, // we already have a copy + // we have a copy of a reference but don't want to mutate the source schema + // TODO might need recursive resolution of references here + OpenApiSchemaReference r when r.Target is not null => (OpenApiSchema)r.Target.CreateShallowCopy(), + OpenApiSchemaReference => throw new InvalidOperationException("Unresolved reference target"), + _ => throw new InvalidOperationException("Unexpected schema type") + }; + + updatedSchema.Type = "file".ToJsonSchemaType(); + updatedSchema.Format = null; + paramSchema = updatedSchema; + + } + yield return new OpenApiFormDataParameter() + { + Description = paramSchema.Description, + Name = property.Key, + Schema = paramSchema, + Examples = Content.Values.FirstOrDefault()?.Examples, + Required = Content.First().Value.Schema?.Required?.Contains(property.Key) ?? false }; - updatedSchema.Type = "file".ToJsonSchemaType(); - updatedSchema.Format = null; - paramSchema = updatedSchema; } - yield return new OpenApiFormDataParameter() - { - Description = paramSchema.Description, - Name = property.Key, - Schema = paramSchema, - Examples = Content.Values.FirstOrDefault()?.Examples, - Required = Content.First().Value.Schema.Required?.Contains(property.Key) ?? false - }; - } + } } /// diff --git a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs index 0ec6cbb84..9c8459e2b 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs @@ -16,19 +16,19 @@ namespace Microsoft.OpenApi.Models public class OpenApiResponse : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiResponse { /// - public string Description { get; set; } + public string? Description { get; set; } /// - public IDictionary Headers { get; set; } = new Dictionary(); + public IDictionary? Headers { get; set; } = new Dictionary(); /// - public IDictionary Content { get; set; } = new Dictionary(); + public IDictionary? Content { get; set; } = new Dictionary(); /// - public IDictionary Links { get; set; } = new Dictionary(); + public IDictionary? Links { get; set; } = new Dictionary(); /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameterless constructor @@ -101,7 +101,7 @@ public void SerializeAsV2(IOpenApiWriter writer) // description writer.WriteRequiredProperty(OpenApiConstants.Description, Description); - var extensionsClone = new Dictionary(Extensions); + var extensionsClone = Extensions is not null ? new Dictionary(Extensions) : null; if (Content != null) { @@ -135,8 +135,9 @@ public void SerializeAsV2(IOpenApiWriter writer) writer.WriteStartObject(); foreach (var example in Content - .Where(mediaTypePair => mediaTypePair.Value.Examples != null && mediaTypePair.Value.Examples.Any()) - .SelectMany(mediaTypePair => mediaTypePair.Value.Examples)) + .Select(static x => x.Value.Examples) + .OfType>() + .SelectMany(static x => x)) { writer.WritePropertyName(example.Key); example.Value.SerializeAsV2(writer); @@ -147,12 +148,15 @@ public void SerializeAsV2(IOpenApiWriter writer) writer.WriteExtensions(mediatype.Value.Extensions, OpenApiSpecVersion.OpenApi2_0); - foreach (var key in mediatype.Value.Extensions.Keys) + if (mediatype.Value.Extensions is not null) { - // The extension will already have been serialized as part of the call above, - // so remove it from the cloned collection so we don't write it again. - extensionsClone.Remove(key); - } + foreach (var key in mediatype.Value.Extensions.Keys) + { + // The extension will already have been serialized as part of the call above, + // so remove it from the cloned collection so we don't write it again. + extensionsClone?.Remove(key); + } + } } } diff --git a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs index 10f403efc..84e03fcb0 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSchema.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSchema.cs @@ -21,28 +21,28 @@ namespace Microsoft.OpenApi.Models public class OpenApiSchema : IOpenApiExtensible, IOpenApiSchema { /// - public string Title { get; set; } + public string? Title { get; set; } /// - public Uri Schema { get; set; } + public Uri? Schema { get; set; } /// - public string Id { get; set; } + public string? Id { get; set; } /// - public string Comment { get; set; } + public string? Comment { get; set; } /// - public IDictionary Vocabulary { get; set; } + public IDictionary? Vocabulary { get; set; } /// - public string DynamicRef { get; set; } + public string? DynamicRef { get; set; } /// - public string DynamicAnchor { get; set; } + public string? DynamicAnchor { get; set; } /// - public IDictionary Definitions { get; set; } + public IDictionary? Definitions { get; set; } private decimal? _exclusiveMaximum; /// @@ -109,13 +109,13 @@ public decimal? ExclusiveMinimum public JsonSchemaType? Type { get; set; } /// - public string Const { get; set; } + public string? Const { get; set; } /// - public string Format { get; set; } + public string? Format { get; set; } /// - public string Description { get; set; } + public string? Description { get; set; } private decimal? _maximum; /// @@ -161,13 +161,13 @@ public decimal? Minimum public int? MinLength { get; set; } /// - public string Pattern { get; set; } + public string? Pattern { get; set; } /// public decimal? MultipleOf { get; set; } /// - public JsonNode Default { get; set; } + public JsonNode? Default { get; set; } /// public bool ReadOnly { get; set; } @@ -176,22 +176,22 @@ public decimal? Minimum public bool WriteOnly { get; set; } /// - public IList AllOf { get; set; } = []; + public IList? AllOf { get; set; } = []; /// - public IList OneOf { get; set; } = []; + public IList? OneOf { get; set; } = []; /// - public IList AnyOf { get; set; } = []; + public IList? AnyOf { get; set; } = []; /// - public IOpenApiSchema Not { get; set; } + public IOpenApiSchema? Not { get; set; } /// - public ISet Required { get; set; } = new HashSet(); + public ISet? Required { get; set; } = new HashSet(); /// - public IOpenApiSchema Items { get; set; } + public IOpenApiSchema? Items { get; set; } /// public int? MaxItems { get; set; } @@ -203,10 +203,10 @@ public decimal? Minimum public bool? UniqueItems { get; set; } /// - public IDictionary Properties { get; set; } = new Dictionary(StringComparer.Ordinal); + public IDictionary? Properties { get; set; } = new Dictionary(StringComparer.Ordinal); /// - public IDictionary PatternProperties { get; set; } = new Dictionary(StringComparer.Ordinal); + public IDictionary? PatternProperties { get; set; } = new Dictionary(StringComparer.Ordinal); /// public int? MaxProperties { get; set; } @@ -218,43 +218,43 @@ public decimal? Minimum public bool AdditionalPropertiesAllowed { get; set; } = true; /// - public IOpenApiSchema AdditionalProperties { get; set; } + public IOpenApiSchema? AdditionalProperties { get; set; } /// - public OpenApiDiscriminator Discriminator { get; set; } + public OpenApiDiscriminator? Discriminator { get; set; } /// - public JsonNode Example { get; set; } + public JsonNode? Example { get; set; } /// - public IList Examples { get; set; } + public IList? Examples { get; set; } /// - public IList Enum { get; set; } = new List(); + public IList? Enum { get; set; } = new List(); /// public bool UnevaluatedProperties { get; set;} /// - public OpenApiExternalDocs ExternalDocs { get; set; } + public OpenApiExternalDocs? ExternalDocs { get; set; } /// public bool Deprecated { get; set; } /// - public OpenApiXml Xml { get; set; } + public OpenApiXml? Xml { get; set; } /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// - public IDictionary UnrecognizedKeywords { get; set; } = new Dictionary(); + public IDictionary? UnrecognizedKeywords { get; set; } = new Dictionary(); /// - public IDictionary Annotations { get; set; } + public IDictionary? Annotations { get; set; } /// - public IDictionary> DependentRequired { get; set; } = new Dictionary>(); + public IDictionary>? DependentRequired { get; set; } = new Dictionary>(); /// /// Parameterless constructor @@ -424,7 +424,13 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version writer.WriteProperty(OpenApiConstants.MinProperties, MinProperties); // required - writer.WriteOptionalCollection(OpenApiConstants.Required, Required, (w, s) => w.WriteValue(s)); + writer.WriteOptionalCollection(OpenApiConstants.Required, Required, (w, s) => + { + if (!string.IsNullOrEmpty(s) && s is not null) + { + w.WriteValue(s); + } + }); // enum writer.WriteOptionalCollection(OpenApiConstants.Enum, Enum, (nodeWriter, s) => nodeWriter.WriteAny(s)); @@ -497,7 +503,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version writer.WriteExtensions(Extensions, version); // Unrecognized keywords - if (UnrecognizedKeywords.Any()) + if (UnrecognizedKeywords is not null && UnrecognizedKeywords.Any()) { writer.WriteOptionalMap(OpenApiConstants.UnrecognizedKeywords, UnrecognizedKeywords, (w,s) => w.WriteAny(s)); } @@ -604,8 +610,8 @@ private void WriteFormatProperty(IOpenApiWriter writer) /// The property name that will be serialized. private void SerializeAsV2( IOpenApiWriter writer, - ISet parentRequiredProperties, - string propertyName) + ISet? parentRequiredProperties, + string? propertyName) { parentRequiredProperties ??= new HashSet(); @@ -662,7 +668,13 @@ private void SerializeAsV2( writer.WriteProperty(OpenApiConstants.MinProperties, MinProperties); // required - writer.WriteOptionalCollection(OpenApiConstants.Required, Required, (w, s) => w.WriteValue(s)); + writer.WriteOptionalCollection(OpenApiConstants.Required, Required, (w, s) => + { + if (!string.IsNullOrEmpty(s) && s is not null) + { + w.WriteValue(s); + } + }); // enum writer.WriteOptionalCollection(OpenApiConstants.Enum, Enum, (w, s) => w.WriteAny(s)); @@ -715,7 +727,7 @@ private void SerializeAsV2( // readOnly // In V2 schema if a property is part of required properties of parent schema, // it cannot be marked as readonly. - if (!parentRequiredProperties.Contains(propertyName)) + if (!string.IsNullOrEmpty(propertyName) && propertyName is not null && !parentRequiredProperties.Contains(propertyName)) { writer.WriteProperty(name: OpenApiConstants.ReadOnly, value: ReadOnly, defaultValue: false); } @@ -815,7 +827,13 @@ where temporaryType.HasFlag(flag) select flag.ToFirstIdentifier()).ToList(); if (list.Count > 1) { - writer.WriteOptionalCollection(OpenApiConstants.Type, list, (w, s) => w.WriteValue(s)); + writer.WriteOptionalCollection(OpenApiConstants.Type, list, (w, s) => + { + if (!string.IsNullOrEmpty(s) && s is not null) + { + w.WriteValue(s); + } + }); } else { diff --git a/src/Microsoft.OpenApi/Models/OpenApiSecurityRequirement.cs b/src/Microsoft.OpenApi/Models/OpenApiSecurityRequirement.cs index 193d648df..7b2e70d3c 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSecurityRequirement.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSecurityRequirement.cs @@ -37,7 +37,13 @@ public OpenApiSecurityRequirement() /// public void SerializeAsV31(IOpenApiWriter writer) { - SerializeInternal(writer, (w, s) => w.WritePropertyName(s.Reference.ReferenceV3)); + SerializeInternal(writer, (w, s) => + { + if(!string.IsNullOrEmpty(s.Reference.ReferenceV3) && s.Reference.ReferenceV3 is not null) + { + w.WritePropertyName(s.Reference.ReferenceV3); + } + }); } /// @@ -45,7 +51,13 @@ public void SerializeAsV31(IOpenApiWriter writer) /// public void SerializeAsV3(IOpenApiWriter writer) { - SerializeInternal(writer, (w, s) => w.WritePropertyName(s.Reference.ReferenceV3)); + SerializeInternal(writer, (w, s) => + { + if (!string.IsNullOrEmpty(s.Reference.ReferenceV3) && s.Reference.ReferenceV3 is not null) + { + w.WritePropertyName(s.Reference.ReferenceV3); + } + }); } /// @@ -98,7 +110,7 @@ private sealed class OpenApiSecuritySchemeReferenceEqualityComparer : IEqualityC /// /// Determines whether the specified objects are equal. /// - public bool Equals(OpenApiSecuritySchemeReference x, OpenApiSecuritySchemeReference y) + public bool Equals(OpenApiSecuritySchemeReference? x, OpenApiSecuritySchemeReference? y) { if (x == null && y == null) { @@ -122,7 +134,8 @@ public int GetHashCode(OpenApiSecuritySchemeReference obj) { return 0; } - return string.IsNullOrEmpty(obj?.Reference?.Id) ? 0 : obj.Reference.Id.GetHashCode(); + var id = obj.Reference?.Id; + return string.IsNullOrEmpty(id) ? 0 : id!.GetHashCode(); } } } diff --git a/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs b/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs index dddbbffec..7d254a3d2 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs @@ -19,28 +19,28 @@ public class OpenApiSecurityScheme : IOpenApiExtensible, IOpenApiReferenceable, public SecuritySchemeType? Type { get; set; } /// - public string Description { get; set; } + public string? Description { get; set; } /// - public string Name { get; set; } + public string? Name { get; set; } /// public ParameterLocation? In { get; set; } /// - public string Scheme { get; set; } + public string? Scheme { get; set; } /// - public string BearerFormat { get; set; } + public string? BearerFormat { get; set; } /// - public OpenApiOAuthFlows Flows { get; set; } + public OpenApiOAuthFlows? Flows { get; set; } /// - public Uri OpenIdConnectUrl { get; set; } + public Uri? OpenIdConnectUrl { get; set; } /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameterless constructor @@ -88,7 +88,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version writer.WriteStartObject(); // type - writer.WriteProperty(OpenApiConstants.Type, Type.GetDisplayName()); + writer.WriteProperty(OpenApiConstants.Type, Type?.GetDisplayName()); // description writer.WriteProperty(OpenApiConstants.Description, Description); @@ -100,7 +100,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version // name // in writer.WriteProperty(OpenApiConstants.Name, Name); - writer.WriteProperty(OpenApiConstants.In, In.GetDisplayName()); + writer.WriteProperty(OpenApiConstants.In, In?.GetDisplayName()); break; case SecuritySchemeType.Http: // These properties apply to http type only. @@ -175,7 +175,7 @@ public void SerializeAsV2(IOpenApiWriter writer) // in writer.WriteProperty(OpenApiConstants.Type, Type.GetDisplayName()); writer.WriteProperty(OpenApiConstants.Name, Name); - writer.WriteProperty(OpenApiConstants.In, In.GetDisplayName()); + writer.WriteProperty(OpenApiConstants.In, In?.GetDisplayName()); break; } @@ -192,7 +192,7 @@ public void SerializeAsV2(IOpenApiWriter writer) /// Arbitrarily chooses one object from the /// to populate in V2 security scheme. /// - private static void WriteOAuthFlowForV2(IOpenApiWriter writer, OpenApiOAuthFlows flows) + private static void WriteOAuthFlowForV2(IOpenApiWriter writer, OpenApiOAuthFlows? flows) { if (flows != null) { diff --git a/src/Microsoft.OpenApi/Models/OpenApiServer.cs b/src/Microsoft.OpenApi/Models/OpenApiServer.cs index b580f7fbb..a15c6068e 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiServer.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiServer.cs @@ -16,25 +16,25 @@ public class OpenApiServer : IOpenApiSerializable, IOpenApiExtensible /// /// An optional string describing the host designated by the URL. CommonMark syntax MAY be used for rich text representation. /// - public string Description { get; set; } + public string? Description { get; set; } /// /// REQUIRED. A URL to the target host. This URL supports Server Variables and MAY be relative, /// to indicate that the host location is relative to the location where the OpenAPI document is being served. /// Variable substitutions will be made when a variable is named in {brackets}. /// - public string Url { get; set; } + public string? Url { get; set; } /// /// A map between a variable name and its value. The value is used for substitution in the server's URL template. /// - public IDictionary Variables { get; set; } = + public IDictionary? Variables { get; set; } = new Dictionary(); /// /// This object MAY be extended with Specification Extensions. /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameterless constructor @@ -74,7 +74,7 @@ public void SerializeAsV3(IOpenApiWriter writer) private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, Action callback) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); writer.WriteStartObject(); diff --git a/src/Microsoft.OpenApi/Models/OpenApiServerVariable.cs b/src/Microsoft.OpenApi/Models/OpenApiServerVariable.cs index 615b8dc37..9c46f20a8 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiServerVariable.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiServerVariable.cs @@ -15,13 +15,13 @@ public class OpenApiServerVariable : IOpenApiSerializable, IOpenApiExtensible /// /// An optional description for the server variable. CommonMark syntax MAY be used for rich text representation. /// - public string Description { get; set; } + public string? Description { get; set; } /// /// REQUIRED. The default value to use for substitution, and to send, if an alternate value is not supplied. /// Unlike the Schema Object's default, this value MUST be provided by the consumer. /// - public string Default { get; set; } + public string? Default { get; set; } /// /// An enumeration of string values to be used if the substitution options are from a limited set. @@ -29,12 +29,12 @@ public class OpenApiServerVariable : IOpenApiSerializable, IOpenApiExtensible /// /// If the server variable in the OpenAPI document has no enum member, this property will be null. /// - public List Enum { get; set; } + public List? Enum { get; set; } /// /// This object MAY be extended with Specification Extensions. /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameterless constructor @@ -48,8 +48,8 @@ public OpenApiServerVariable(OpenApiServerVariable serverVariable) { Description = serverVariable?.Description; Default = serverVariable?.Default; - Enum = serverVariable?.Enum != null ? new(serverVariable?.Enum) : serverVariable?.Enum; - Extensions = serverVariable?.Extensions != null ? new Dictionary(serverVariable?.Extensions) : serverVariable?.Extensions; + Enum = serverVariable?.Enum != null ? new(serverVariable.Enum) : serverVariable?.Enum; + Extensions = serverVariable?.Extensions != null ? new Dictionary(serverVariable.Extensions) : serverVariable?.Extensions; } /// @@ -73,7 +73,7 @@ public void SerializeAsV3(IOpenApiWriter writer) /// private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); writer.WriteStartObject(); @@ -84,7 +84,13 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version writer.WriteProperty(OpenApiConstants.Description, Description); // enums - writer.WriteOptionalCollection(OpenApiConstants.Enum, Enum, (w, s) => w.WriteValue(s)); + writer.WriteOptionalCollection(OpenApiConstants.Enum, Enum, (w, s) => + { + if (!string.IsNullOrEmpty(s) && s is not null) + { + w.WriteValue(s); + } + }); // specification extensions writer.WriteExtensions(Extensions, version); diff --git a/src/Microsoft.OpenApi/Models/OpenApiTag.cs b/src/Microsoft.OpenApi/Models/OpenApiTag.cs index 91e3aac68..48ac2960c 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiTag.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiTag.cs @@ -15,16 +15,16 @@ namespace Microsoft.OpenApi.Models public class OpenApiTag : IOpenApiExtensible, IOpenApiReferenceable, IOpenApiTag, IOpenApiDescribedElement { /// - public string Name { get; set; } + public string? Name { get; set; } /// - public string Description { get; set; } + public string? Description { get; set; } /// - public OpenApiExternalDocs ExternalDocs { get; set; } + public OpenApiExternalDocs? ExternalDocs { get; set; } /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameterless constructor diff --git a/src/Microsoft.OpenApi/Models/OpenApiXml.cs b/src/Microsoft.OpenApi/Models/OpenApiXml.cs index d0ee6a00b..c0503e14d 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiXml.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiXml.cs @@ -16,17 +16,17 @@ public class OpenApiXml : IOpenApiSerializable, IOpenApiExtensible /// /// Replaces the name of the element/attribute used for the described schema property. /// - public string Name { get; set; } + public string? Name { get; set; } /// /// The URI of the namespace definition. Value MUST be in the form of an absolute URI. /// - public Uri Namespace { get; set; } + public Uri? Namespace { get; set; } /// /// The prefix to be used for the name /// - public string Prefix { get; set; } + public string? Prefix { get; set; } /// /// Declares whether the property definition translates to an attribute instead of an element. @@ -43,7 +43,7 @@ public class OpenApiXml : IOpenApiSerializable, IOpenApiExtensible /// /// Specification Extensions. /// - public IDictionary Extensions { get; set; } = new Dictionary(); + public IDictionary? Extensions { get; set; } = new Dictionary(); /// /// Parameterless constructor @@ -89,7 +89,7 @@ public void SerializeAsV2(IOpenApiWriter writer) private void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); writer.WriteStartObject(); diff --git a/src/Microsoft.OpenApi/Models/References/BaseOpenApiReferenceHolder.cs b/src/Microsoft.OpenApi/Models/References/BaseOpenApiReferenceHolder.cs index ea1839f49..167dcf2c3 100644 --- a/src/Microsoft.OpenApi/Models/References/BaseOpenApiReferenceHolder.cs +++ b/src/Microsoft.OpenApi/Models/References/BaseOpenApiReferenceHolder.cs @@ -11,7 +11,7 @@ namespace Microsoft.OpenApi.Models.References; public abstract class BaseOpenApiReferenceHolder : IOpenApiReferenceHolder where T : class, IOpenApiReferenceable, V where V : IOpenApiReferenceable, IOpenApiSerializable { /// - public virtual V Target + public virtual V? Target { get { @@ -20,7 +20,7 @@ public virtual V Target } } /// - public T RecursiveTarget + public T? RecursiveTarget { get { @@ -31,6 +31,7 @@ public T RecursiveTarget }; } } + /// /// Copy constructor /// @@ -38,7 +39,7 @@ public T RecursiveTarget protected BaseOpenApiReferenceHolder(BaseOpenApiReferenceHolder source) { Utils.CheckArgumentNull(source); - Reference = source.Reference != null ? new(source.Reference) : null; + Reference = new(source.Reference); //no need to copy summary and description as if they are not overridden, they will be fetched from the target //if they are, the reference copy will handle it } @@ -53,7 +54,7 @@ protected BaseOpenApiReferenceHolder(BaseOpenApiReferenceHolder source) /// 1. a absolute/relative file path, for example: ../commons/pet.json /// 2. a Url, for example: http://localhost/pet.json /// - protected BaseOpenApiReferenceHolder(string referenceId, OpenApiDocument hostDocument, ReferenceType referenceType, string externalResource) + protected BaseOpenApiReferenceHolder(string referenceId, OpenApiDocument? hostDocument, ReferenceType referenceType, string? externalResource) { Utils.CheckArgumentNullOrEmpty(referenceId); // we're not checking for null hostDocument as it's optional and can be set via additional methods by a walker @@ -69,8 +70,14 @@ protected BaseOpenApiReferenceHolder(string referenceId, OpenApiDocument hostDoc } /// public bool UnresolvedReference { get => Reference is null || Target is null; } + +#if NETSTANDARD2_1_OR_GREATER + /// + public required OpenApiReference Reference { get; init; } +#else /// public OpenApiReference Reference { get; init; } +#endif /// public abstract V CopyReferenceAsTargetElementWithOverrides(V source); /// @@ -83,7 +90,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer) } else { - SerializeInternal(writer, (writer, element) => element.SerializeAsV3(writer)); + SerializeInternal(writer, (writer, element) => element?.SerializeAsV3(writer)); } } @@ -109,7 +116,7 @@ public virtual void SerializeAsV2(IOpenApiWriter writer) } else { - SerializeInternal(writer, (writer, element) => element.SerializeAsV2(writer)); + SerializeInternal(writer, (writer, element) => element?.SerializeAsV2(writer)); } } @@ -123,6 +130,9 @@ private protected void SerializeInternal(IOpenApiWriter writer, Action action) { Utils.CheckArgumentNull(writer); - action(writer, Target); + if (Target is not null) + { + action(writer, Target); + } } } diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs index 4c30328d4..d1a06da15 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs @@ -25,7 +25,7 @@ public class OpenApiCallbackReference : BaseOpenApiReferenceHolder - public OpenApiCallbackReference(string referenceId, OpenApiDocument hostDocument = null, string externalResource = null):base(referenceId, hostDocument, ReferenceType.Callback, externalResource) + public OpenApiCallbackReference(string referenceId, OpenApiDocument? hostDocument = null, string? externalResource = null):base(referenceId, hostDocument, ReferenceType.Callback, externalResource) { } /// @@ -38,10 +38,10 @@ private OpenApiCallbackReference(OpenApiCallbackReference callback):base(callbac } /// - public Dictionary PathItems { get => Target?.PathItems; } + public Dictionary? PathItems { get => Target?.PathItems; } /// - public IDictionary Extensions { get => Target?.Extensions; } + public IDictionary? Extensions { get => Target?.Extensions; } /// public override IOpenApiCallback CopyReferenceAsTargetElementWithOverrides(IOpenApiCallback source) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs index edfe27b61..b1c1ae8ae 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs @@ -25,7 +25,7 @@ public class OpenApiExampleReference : BaseOpenApiReferenceHolder - public OpenApiExampleReference(string referenceId, OpenApiDocument hostDocument = null, string externalResource = null):base(referenceId, hostDocument, ReferenceType.Example, externalResource) + public OpenApiExampleReference(string referenceId, OpenApiDocument? hostDocument = null, string? externalResource = null):base(referenceId, hostDocument, ReferenceType.Example, externalResource) { } /// @@ -37,39 +37,27 @@ private OpenApiExampleReference(OpenApiExampleReference example):base(example) } /// - public string Description + public string? Description { - get => string.IsNullOrEmpty(Reference?.Description) ? Target?.Description : Reference.Description; - set - { - if (Reference is not null) - { - Reference.Description = value; - } - } + get => string.IsNullOrEmpty(Reference.Description) ? Target?.Description : Reference.Description; + set => Reference.Description = value; } /// - public string Summary + public string? Summary { - get => string.IsNullOrEmpty(Reference?.Summary) ? Target?.Summary : Reference.Summary; - set - { - if (Reference is not null) - { - Reference.Summary = value; - } - } + get => string.IsNullOrEmpty(Reference.Summary) ? Target?.Summary : Reference.Summary; + set => Reference.Summary = value; } /// - public IDictionary Extensions { get => Target?.Extensions; } + public IDictionary? Extensions { get => Target?.Extensions; } /// - public string ExternalValue { get => Target?.ExternalValue; } + public string? ExternalValue { get => Target?.ExternalValue; } /// - public JsonNode Value { get => Target?.Value; } + public JsonNode? Value { get => Target?.Value; } /// public override IOpenApiExample CopyReferenceAsTargetElementWithOverrides(IOpenApiExample source) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiHeaderReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiHeaderReference.cs index 719cdce3a..cd843de57 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiHeaderReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiHeaderReference.cs @@ -24,7 +24,7 @@ public class OpenApiHeaderReference : BaseOpenApiReferenceHolder - public OpenApiHeaderReference(string referenceId, OpenApiDocument hostDocument = null, string externalResource = null):base(referenceId, hostDocument, ReferenceType.Header, externalResource) + public OpenApiHeaderReference(string referenceId, OpenApiDocument? hostDocument = null, string? externalResource = null):base(referenceId, hostDocument, ReferenceType.Header, externalResource) { } @@ -37,16 +37,10 @@ private OpenApiHeaderReference(OpenApiHeaderReference header):base(header) } /// - public string Description + public string? Description { - get => string.IsNullOrEmpty(Reference?.Description) ? Target?.Description : Reference.Description; - set - { - if (Reference is not null) - { - Reference.Description = value; - } - } + get => string.IsNullOrEmpty(Reference.Description) ? Target?.Description : Reference.Description; + set => Reference.Description = value; } /// @@ -59,7 +53,7 @@ public string Description public bool AllowEmptyValue { get => Target?.AllowEmptyValue ?? default; } /// - public IOpenApiSchema Schema { get => Target?.Schema; } + public IOpenApiSchema? Schema { get => Target?.Schema; } /// public ParameterStyle? Style { get => Target?.Style; } @@ -71,16 +65,16 @@ public string Description public bool AllowReserved { get => Target?.AllowReserved ?? default; } /// - public JsonNode Example { get => Target?.Example; } + public JsonNode? Example { get => Target?.Example; } /// - public IDictionary Examples { get => Target?.Examples; } + public IDictionary? Examples { get => Target?.Examples; } /// - public IDictionary Content { get => Target?.Content; } + public IDictionary? Content { get => Target?.Content; } /// - public IDictionary Extensions { get => Target?.Extensions; } + public IDictionary? Extensions { get => Target?.Extensions; } /// public override IOpenApiHeader CopyReferenceAsTargetElementWithOverrides(IOpenApiHeader source) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs index f91b5711b..8c23cdf35 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs @@ -24,7 +24,7 @@ public class OpenApiLinkReference : BaseOpenApiReferenceHolder - public OpenApiLinkReference(string referenceId, OpenApiDocument hostDocument = null, string externalResource = null):base(referenceId, hostDocument, ReferenceType.Link, externalResource) + public OpenApiLinkReference(string referenceId, OpenApiDocument? hostDocument = null, string? externalResource = null):base(referenceId, hostDocument, ReferenceType.Link, externalResource) { } /// @@ -36,35 +36,29 @@ private OpenApiLinkReference(OpenApiLinkReference reference):base(reference) } /// - public string Description + public string? Description { - get => string.IsNullOrEmpty(Reference?.Description) ? Target?.Description : Reference.Description; - set - { - if (Reference is not null) - { - Reference.Description = value; - } - } + get => string.IsNullOrEmpty(Reference.Description) ? Target?.Description : Reference.Description; + set => Reference.Description = value; } /// - public string OperationRef { get => Target?.OperationRef; } + public string? OperationRef { get => Target?.OperationRef; } /// - public string OperationId { get => Target?.OperationId; } + public string? OperationId { get => Target?.OperationId; } /// - public OpenApiServer Server { get => Target?.Server; } + public OpenApiServer? Server { get => Target?.Server; } /// - public IDictionary Parameters { get => Target?.Parameters; } + public IDictionary? Parameters { get => Target?.Parameters; } /// - public RuntimeExpressionAnyWrapper RequestBody { get => Target?.RequestBody; } + public RuntimeExpressionAnyWrapper? RequestBody { get => Target?.RequestBody; } /// - public IDictionary Extensions { get => Target?.Extensions; } + public IDictionary? Extensions { get => Target?.Extensions; } /// public override void SerializeAsV2(IOpenApiWriter writer) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs index d337b841e..40ecb69eb 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs @@ -23,7 +23,7 @@ public class OpenApiParameterReference : BaseOpenApiReferenceHolder - public OpenApiParameterReference(string referenceId, OpenApiDocument hostDocument = null, string externalResource = null):base(referenceId, hostDocument, ReferenceType.Parameter, externalResource) + public OpenApiParameterReference(string referenceId, OpenApiDocument? hostDocument = null, string? externalResource = null):base(referenceId, hostDocument, ReferenceType.Parameter, externalResource) { } @@ -36,19 +36,13 @@ private OpenApiParameterReference(OpenApiParameterReference parameter):base(para } /// - public string Name { get => Target?.Name; } + public string? Name { get => Target?.Name; } /// - public string Description + public string? Description { - get => string.IsNullOrEmpty(Reference?.Description) ? Target?.Description : Reference.Description; - set - { - if (Reference is not null) - { - Reference.Description = value; - } - } + get => string.IsNullOrEmpty(Reference.Description) ? Target?.Description : Reference.Description; + set => Reference.Description = value; } /// @@ -64,13 +58,13 @@ public string Description public bool AllowReserved { get => Target?.AllowReserved ?? default; } /// - public IOpenApiSchema Schema { get => Target?.Schema; } + public IOpenApiSchema? Schema { get => Target?.Schema; } /// - public IDictionary Examples { get => Target?.Examples; } + public IDictionary? Examples { get => Target?.Examples; } /// - public JsonNode Example { get => Target?.Example; } + public JsonNode? Example { get => Target?.Example; } /// public ParameterLocation? In { get => Target?.In; } @@ -82,13 +76,13 @@ public string Description public bool Explode { get => Target?.Explode ?? default; } /// - public IDictionary Content { get => Target?.Content; } + public IDictionary? Content { get => Target?.Content; } /// - public IDictionary Extensions { get => Target?.Extensions; } + public IDictionary? Extensions { get => Target?.Extensions; } /// - public override IOpenApiParameter CopyReferenceAsTargetElementWithOverrides(IOpenApiParameter source) + public override IOpenApiParameter CopyReferenceAsTargetElementWithOverrides(IOpenApiParameter source) { return source is OpenApiParameter ? new OpenApiParameter(this) : source; } diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiPathItemReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiPathItemReference.cs index d56d07c21..bfd9f8ceb 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiPathItemReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiPathItemReference.cs @@ -25,7 +25,7 @@ public class OpenApiPathItemReference : BaseOpenApiReferenceHolder - public OpenApiPathItemReference(string referenceId, OpenApiDocument hostDocument = null, string externalResource = null): base(referenceId, hostDocument, ReferenceType.PathItem, externalResource) + public OpenApiPathItemReference(string referenceId, OpenApiDocument? hostDocument = null, string? externalResource = null): base(referenceId, hostDocument, ReferenceType.PathItem, externalResource) { } @@ -39,42 +39,30 @@ private OpenApiPathItemReference(OpenApiPathItemReference pathItem):base(pathIte } /// - public string Summary + public string? Summary { - get => string.IsNullOrEmpty(Reference?.Summary) ? Target?.Summary : Reference.Summary; - set - { - if (Reference is not null) - { - Reference.Summary = value; - } - } + get => string.IsNullOrEmpty(Reference.Summary) ? Target?.Summary : Reference.Summary; + set => Reference.Summary = value; } /// - public string Description + public string? Description { - get => string.IsNullOrEmpty(Reference?.Description) ? Target?.Description : Reference.Description; - set - { - if (Reference is not null) - { - Reference.Description = value; - } - } + get => string.IsNullOrEmpty(Reference.Description) ? Target?.Description : Reference.Description; + set => Reference.Description = value; } /// - public IDictionary Operations { get => Target?.Operations; } + public IDictionary? Operations { get => Target?.Operations; } /// - public IList Servers { get => Target?.Servers; } + public IList? Servers { get => Target?.Servers; } /// - public IList Parameters { get => Target?.Parameters; } + public IList? Parameters { get => Target?.Parameters; } /// - public IDictionary Extensions { get => Target?.Extensions; } + public IDictionary? Extensions { get => Target?.Extensions; } /// public override IOpenApiPathItem CopyReferenceAsTargetElementWithOverrides(IOpenApiPathItem source) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiRequestBodyReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiRequestBodyReference.cs index 966d3aad1..8beb3e604 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiRequestBodyReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiRequestBodyReference.cs @@ -25,7 +25,7 @@ public class OpenApiRequestBodyReference : BaseOpenApiReferenceHolder - public OpenApiRequestBodyReference(string referenceId, OpenApiDocument hostDocument = null, string externalResource = null):base(referenceId, hostDocument, ReferenceType.RequestBody, externalResource) + public OpenApiRequestBodyReference(string referenceId, OpenApiDocument? hostDocument = null, string? externalResource = null):base(referenceId, hostDocument, ReferenceType.RequestBody, externalResource) { } /// @@ -38,26 +38,20 @@ private OpenApiRequestBodyReference(OpenApiRequestBodyReference openApiRequestBo } /// - public string Description + public string? Description { - get => string.IsNullOrEmpty(Reference?.Description) ? Target?.Description : Reference.Description; - set - { - if (Reference is not null) - { - Reference.Description = value; - } - } + get => string.IsNullOrEmpty(Reference.Description) ? Target?.Description : Reference.Description; + set => Reference.Description = value; } /// - public IDictionary Content { get => Target?.Content; } + public IDictionary? Content { get => Target?.Content; } /// public bool Required { get => Target?.Required ?? false; } /// - public IDictionary Extensions { get => Target?.Extensions; } + public IDictionary? Extensions { get => Target?.Extensions; } /// public override IOpenApiRequestBody CopyReferenceAsTargetElementWithOverrides(IOpenApiRequestBody source) @@ -70,29 +64,27 @@ public override void SerializeAsV2(IOpenApiWriter writer) // doesn't exist in v2 } /// - public IOpenApiParameter ConvertToBodyParameter(IOpenApiWriter writer) + public IOpenApiParameter? ConvertToBodyParameter(IOpenApiWriter writer) { if (writer.GetSettings().ShouldInlineReference(Reference)) { - return Target.ConvertToBodyParameter(writer); - } - else - { - return new OpenApiParameterReference(Reference.Id, Reference.HostDocument); + return Target?.ConvertToBodyParameter(writer); } + + return Reference.Id is not null ? new OpenApiParameterReference(Reference.Id, Reference.HostDocument) : null; } /// - public IEnumerable ConvertToFormDataParameters(IOpenApiWriter writer) + public IEnumerable? ConvertToFormDataParameters(IOpenApiWriter writer) { if (writer.GetSettings().ShouldInlineReference(Reference)) { - return Target.ConvertToFormDataParameters(writer); + return Target?.ConvertToFormDataParameters(writer); } if (Content == null || !Content.Any()) return []; - return Content.First().Value.Schema.Properties.Select(x => new OpenApiParameterReference(x.Key, Reference.HostDocument)); + return Content.First().Value.Schema?.Properties?.Select(x => new OpenApiParameterReference(x.Key, Reference.HostDocument)); } /// diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs index 9fbfb47a0..cc78f6080 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs @@ -23,7 +23,7 @@ public class OpenApiResponseReference : BaseOpenApiReferenceHolder - public OpenApiResponseReference(string referenceId, OpenApiDocument hostDocument = null, string externalResource = null):base(referenceId, hostDocument, ReferenceType.Response, externalResource) + public OpenApiResponseReference(string referenceId, OpenApiDocument? hostDocument = null, string? externalResource = null):base(referenceId, hostDocument, ReferenceType.Response, externalResource) { } /// @@ -36,29 +36,23 @@ private OpenApiResponseReference(OpenApiResponseReference openApiResponseReferen } /// - public string Description + public string? Description { - get => string.IsNullOrEmpty(Reference?.Description) ? Target?.Description : Reference.Description; - set - { - if (Reference is not null) - { - Reference.Description = value; - } - } + get => string.IsNullOrEmpty(Reference.Description) ? Target?.Description : Reference.Description; + set => Reference.Description = value; } /// - public IDictionary Content { get => Target?.Content; } + public IDictionary? Content { get => Target?.Content; } /// - public IDictionary Headers { get => Target?.Headers; } + public IDictionary? Headers { get => Target?.Headers; } /// - public IDictionary Links { get => Target?.Links; } + public IDictionary? Links { get => Target?.Links; } /// - public IDictionary Extensions { get => Target?.Extensions; } + public IDictionary? Extensions { get => Target?.Extensions; } /// public override IOpenApiResponse CopyReferenceAsTargetElementWithOverrides(IOpenApiResponse source) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs index 8a5a84d93..2873065fd 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs @@ -25,7 +25,7 @@ public class OpenApiSchemaReference : BaseOpenApiReferenceHolder - public OpenApiSchemaReference(string referenceId, OpenApiDocument hostDocument = null, string externalResource = null):base(referenceId, hostDocument, ReferenceType.Schema, externalResource) + public OpenApiSchemaReference(string referenceId, OpenApiDocument? hostDocument = null, string? externalResource = null):base(referenceId, hostDocument, ReferenceType.Schema, externalResource) { } /// @@ -37,34 +37,28 @@ private OpenApiSchemaReference(OpenApiSchemaReference schema):base(schema) } /// - public string Description + public string? Description { - get => string.IsNullOrEmpty(Reference?.Description) ? Target?.Description : Reference.Description; - set - { - if (Reference is not null) - { - Reference.Description = value; - } - } + get => string.IsNullOrEmpty(Reference.Description) ? Target?.Description : Reference.Description; + set => Reference.Description = value; } /// - public string Title { get => Target?.Title; } + public string? Title { get => Target?.Title; } /// - public Uri Schema { get => Target?.Schema; } + public Uri? Schema { get => Target?.Schema; } /// - public string Id { get => Target?.Id; } + public string? Id { get => Target?.Id; } /// - public string Comment { get => Target?.Comment; } + public string? Comment { get => Target?.Comment; } /// - public IDictionary Vocabulary { get => Target?.Vocabulary; } + public IDictionary? Vocabulary { get => Target?.Vocabulary; } /// - public string DynamicRef { get => Target?.DynamicRef; } + public string? DynamicRef { get => Target?.DynamicRef; } /// - public string DynamicAnchor { get => Target?.DynamicAnchor; } + public string? DynamicAnchor { get => Target?.DynamicAnchor; } /// - public IDictionary Definitions { get => Target?.Definitions; } + public IDictionary? Definitions { get => Target?.Definitions; } /// public decimal? ExclusiveMaximum { get => Target?.ExclusiveMaximum; } /// @@ -74,9 +68,9 @@ public string Description /// public JsonSchemaType? Type { get => Target?.Type; } /// - public string Const { get => Target?.Const; } + public string? Const { get => Target?.Const; } /// - public string Format { get => Target?.Format; } + public string? Format { get => Target?.Format; } /// public decimal? Maximum { get => Target?.Maximum; } /// @@ -86,27 +80,27 @@ public string Description /// public int? MinLength { get => Target?.MinLength; } /// - public string Pattern { get => Target?.Pattern; } + public string? Pattern { get => Target?.Pattern; } /// public decimal? MultipleOf { get => Target?.MultipleOf; } /// - public JsonNode Default { get => Target?.Default; } + public JsonNode? Default { get => Target?.Default; } /// public bool ReadOnly { get => Target?.ReadOnly ?? false; } /// public bool WriteOnly { get => Target?.WriteOnly ?? false; } /// - public IList AllOf { get => Target?.AllOf; } + public IList? AllOf { get => Target?.AllOf; } /// - public IList OneOf { get => Target?.OneOf; } + public IList? OneOf { get => Target?.OneOf; } /// - public IList AnyOf { get => Target?.AnyOf; } + public IList? AnyOf { get => Target?.AnyOf; } /// - public IOpenApiSchema Not { get => Target?.Not; } + public IOpenApiSchema? Not { get => Target?.Not; } /// - public ISet Required { get => Target?.Required; } + public ISet? Required { get => Target?.Required; } /// - public IOpenApiSchema Items { get => Target?.Items; } + public IOpenApiSchema? Items { get => Target?.Items; } /// public int? MaxItems { get => Target?.MaxItems; } /// @@ -114,9 +108,9 @@ public string Description /// public bool? UniqueItems { get => Target?.UniqueItems; } /// - public IDictionary Properties { get => Target?.Properties; } + public IDictionary? Properties { get => Target?.Properties; } /// - public IDictionary PatternProperties { get => Target?.PatternProperties; } + public IDictionary? PatternProperties { get => Target?.PatternProperties; } /// public int? MaxProperties { get => Target?.MaxProperties; } /// @@ -124,34 +118,34 @@ public string Description /// public bool AdditionalPropertiesAllowed { get => Target?.AdditionalPropertiesAllowed ?? true; } /// - public IOpenApiSchema AdditionalProperties { get => Target?.AdditionalProperties; } + public IOpenApiSchema? AdditionalProperties { get => Target?.AdditionalProperties; } /// - public OpenApiDiscriminator Discriminator { get => Target?.Discriminator; } + public OpenApiDiscriminator? Discriminator { get => Target?.Discriminator; } /// - public JsonNode Example { get => Target?.Example; } + public JsonNode? Example { get => Target?.Example; } /// - public IList Examples { get => Target?.Examples; } + public IList? Examples { get => Target?.Examples; } /// - public IList Enum { get => Target?.Enum; } + public IList? Enum { get => Target?.Enum; } /// public bool UnevaluatedProperties { get => Target?.UnevaluatedProperties ?? false; } /// - public OpenApiExternalDocs ExternalDocs { get => Target?.ExternalDocs; } + public OpenApiExternalDocs? ExternalDocs { get => Target?.ExternalDocs; } /// public bool Deprecated { get => Target?.Deprecated ?? false; } /// - public OpenApiXml Xml { get => Target?.Xml; } + public OpenApiXml? Xml { get => Target?.Xml; } /// - public IDictionary Extensions { get => Target?.Extensions; } + public IDictionary? Extensions { get => Target?.Extensions; } /// - public IDictionary UnrecognizedKeywords { get => Target?.UnrecognizedKeywords; } + public IDictionary? UnrecognizedKeywords { get => Target?.UnrecognizedKeywords; } /// - public IDictionary Annotations { get => Target?.Annotations; } + public IDictionary? Annotations { get => Target?.Annotations; } /// - public IDictionary> DependentRequired { get => Target?.DependentRequired; } + public IDictionary>? DependentRequired { get => Target?.DependentRequired; } /// public override void SerializeAsV31(IOpenApiWriter writer) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs index 75ca30573..44741467b 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs @@ -19,7 +19,7 @@ public class OpenApiSecuritySchemeReference : BaseOpenApiReferenceHolderThe reference Id. /// The host OpenAPI document. /// The externally referenced file. - public OpenApiSecuritySchemeReference(string referenceId, OpenApiDocument hostDocument = null, string externalResource = null):base(referenceId, hostDocument, ReferenceType.SecurityScheme, externalResource) + public OpenApiSecuritySchemeReference(string referenceId, OpenApiDocument? hostDocument = null, string? externalResource = null):base(referenceId, hostDocument, ReferenceType.SecurityScheme, externalResource) { } /// @@ -32,38 +32,32 @@ private OpenApiSecuritySchemeReference(OpenApiSecuritySchemeReference openApiSec } /// - public string Description + public string? Description { - get => string.IsNullOrEmpty(Reference?.Description) ? Target?.Description : Reference.Description; - set - { - if (Reference is not null) - { - Reference.Description = value; - } - } + get => string.IsNullOrEmpty(Reference.Description) ? Target?.Description : Reference.Description; + set => Reference.Description = value; } /// - public string Name { get => Target?.Name; } + public string? Name { get => Target?.Name; } /// public ParameterLocation? In { get => Target?.In; } /// - public string Scheme { get => Target?.Scheme; } + public string? Scheme { get => Target?.Scheme; } /// - public string BearerFormat { get => Target?.BearerFormat; } + public string? BearerFormat { get => Target?.BearerFormat; } /// - public OpenApiOAuthFlows Flows { get => Target?.Flows; } + public OpenApiOAuthFlows? Flows { get => Target?.Flows; } /// - public Uri OpenIdConnectUrl { get => Target?.OpenIdConnectUrl; } + public Uri? OpenIdConnectUrl { get => Target?.OpenIdConnectUrl; } /// - public IDictionary Extensions { get => Target?.Extensions; } + public IDictionary? Extensions { get => Target?.Extensions; } /// public SecuritySchemeType? Type { get => Target?.Type; } diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs index 031b5dbb1..59255a8b6 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs @@ -17,7 +17,7 @@ public class OpenApiTagReference : BaseOpenApiReferenceHolder /// Resolved target of the reference. /// - public override IOpenApiTag Target + public override IOpenApiTag? Target { get { @@ -35,7 +35,7 @@ public override IOpenApiTag Target /// 1. a absolute/relative file path, for example: ../commons/pet.json /// 2. a Url, for example: http://localhost/pet.json /// - public OpenApiTagReference(string referenceId, OpenApiDocument hostDocument = null, string externalResource = null):base(referenceId, hostDocument, ReferenceType.Tag, externalResource) + public OpenApiTagReference(string referenceId, OpenApiDocument? hostDocument = null, string? externalResource = null):base(referenceId, hostDocument, ReferenceType.Tag, externalResource) { } /// @@ -48,19 +48,19 @@ private OpenApiTagReference(OpenApiTagReference openApiTagReference):base(openAp } /// - public string Description + public string? Description { - get => string.IsNullOrEmpty(Reference?.Description) ? Target?.Description : Reference.Description; + get => string.IsNullOrEmpty(Reference.Description) ? Target?.Description : Reference.Description; } /// - public OpenApiExternalDocs ExternalDocs { get => Target?.ExternalDocs; } + public OpenApiExternalDocs? ExternalDocs { get => Target?.ExternalDocs; } /// - public IDictionary Extensions { get => Target?.Extensions; } + public IDictionary? Extensions { get => Target?.Extensions; } /// - public string Name { get => Target?.Name; } + public string? Name { get => Target?.Name; } /// public override IOpenApiTag CopyReferenceAsTargetElementWithOverrides(IOpenApiTag source) { diff --git a/src/Microsoft.OpenApi/Models/RuntimeExpressionAnyWrapper.cs b/src/Microsoft.OpenApi/Models/RuntimeExpressionAnyWrapper.cs index 35a08a422..d998ba400 100644 --- a/src/Microsoft.OpenApi/Models/RuntimeExpressionAnyWrapper.cs +++ b/src/Microsoft.OpenApi/Models/RuntimeExpressionAnyWrapper.cs @@ -14,8 +14,8 @@ namespace Microsoft.OpenApi.Models /// public class RuntimeExpressionAnyWrapper : IOpenApiElement { - private JsonNode _any; - private RuntimeExpression _expression; + private JsonNode? _any; + private RuntimeExpression? _expression; /// /// Parameterless constructor @@ -34,7 +34,7 @@ public RuntimeExpressionAnyWrapper(RuntimeExpressionAnyWrapper runtimeExpression /// /// Gets/Sets the /// - public JsonNode Any + public JsonNode? Any { get { @@ -50,7 +50,7 @@ public JsonNode Any /// /// Gets/Set the /// - public RuntimeExpression Expression + public RuntimeExpression? Expression { get { diff --git a/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs b/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs index e8dee12d1..b64c7ea43 100644 --- a/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs +++ b/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs @@ -10,7 +10,7 @@ namespace Microsoft.OpenApi.Reader { internal static class JsonNodeHelper { - public static string GetScalarValue(this JsonNode node) + 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/OpenApiDiagnostic.cs b/src/Microsoft.OpenApi/Reader/OpenApiDiagnostic.cs index 5340d2aef..247bb2ba8 100644 --- a/src/Microsoft.OpenApi/Reader/OpenApiDiagnostic.cs +++ b/src/Microsoft.OpenApi/Reader/OpenApiDiagnostic.cs @@ -33,7 +33,7 @@ public class OpenApiDiagnostic : IDiagnostic /// /// The diagnostic instance of which the errors and warnings are to be appended to this diagnostic's /// The originating file of the diagnostic to be appended, this is prefixed to each error and warning to indicate the originating file - public void AppendDiagnostic(OpenApiDiagnostic diagnosticToAdd, string fileNameToAdd = null) + public void AppendDiagnostic(OpenApiDiagnostic diagnosticToAdd, string? fileNameToAdd = null) { var fileNameIsSupplied = !string.IsNullOrEmpty(fileNameToAdd); foreach (var err in diagnosticToAdd.Errors) diff --git a/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs b/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs index bac24a51d..87a56d90d 100644 --- a/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs +++ b/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs @@ -33,14 +33,14 @@ public ReadResult Read(MemoryStream input, if (input is null) throw new ArgumentNullException(nameof(input)); if (settings is null) throw new ArgumentNullException(nameof(settings)); - JsonNode jsonNode; + JsonNode? jsonNode; var diagnostic = new OpenApiDiagnostic(); settings ??= new OpenApiReaderSettings(); // Parse the JSON text in the stream into JsonNodes try { - jsonNode = JsonNode.Parse(input); + jsonNode = JsonNode.Parse(input) ?? throw new InvalidOperationException($"Cannot parse input stream, {nameof(input)}."); } catch (JsonException ex) { @@ -75,7 +75,7 @@ public ReadResult Read(JsonNode jsonNode, DefaultContentType = settings.DefaultContentType }; - OpenApiDocument document = null; + OpenApiDocument? document = null; try { // Parse the OpenAPI Document @@ -88,17 +88,20 @@ public ReadResult Read(JsonNode jsonNode, } // Validate the document - if (settings.RuleSet != null && settings.RuleSet.Rules.Any()) + if (document is not null && settings.RuleSet is not null && settings.RuleSet.Rules.Any()) { var openApiErrors = document.Validate(settings.RuleSet); - foreach (var item in openApiErrors.OfType()) - { - diagnostic.Errors.Add(item); - } - foreach (var item in openApiErrors.OfType()) + if(openApiErrors is not null) { - diagnostic.Warnings.Add(item); - } + foreach (var item in openApiErrors.OfType()) + { + diagnostic.Errors.Add(item); + } + foreach (var item in openApiErrors.OfType()) + { + diagnostic.Warnings.Add(item); + } + } } return new() @@ -122,13 +125,14 @@ public async Task ReadAsync(Stream input, if (input is null) throw new ArgumentNullException(nameof(input)); if (settings is null) throw new ArgumentNullException(nameof(settings)); - JsonNode jsonNode; + JsonNode? jsonNode; var diagnostic = new OpenApiDiagnostic(); // Parse the JSON text in the stream into JsonNodes try { - jsonNode = await JsonNode.ParseAsync(input, cancellationToken: cancellationToken).ConfigureAwait(false); + jsonNode = await JsonNode.ParseAsync(input, cancellationToken: cancellationToken).ConfigureAwait(false) ?? + throw new InvalidOperationException($"failed to parse input stream, {nameof(input)}"); } catch (JsonException ex) { @@ -144,11 +148,11 @@ public async Task ReadAsync(Stream input, } /// - public T ReadFragment(MemoryStream input, + public T? ReadFragment(MemoryStream input, OpenApiSpecVersion version, OpenApiDocument openApiDocument, out OpenApiDiagnostic diagnostic, - OpenApiReaderSettings settings = null) where T : IOpenApiElement + OpenApiReaderSettings? settings = null) where T : IOpenApiElement { Utils.CheckArgumentNull(input); Utils.CheckArgumentNull(openApiDocument); @@ -158,7 +162,7 @@ public T ReadFragment(MemoryStream input, // Parse the JSON try { - jsonNode = JsonNode.Parse(input); + jsonNode = JsonNode.Parse(input) ?? throw new InvalidOperationException($"Failed to parse stream, {nameof(input)}"); } catch (JsonException ex) { @@ -171,11 +175,11 @@ public T ReadFragment(MemoryStream input, } /// - public T ReadFragment(JsonNode input, - OpenApiSpecVersion version, - OpenApiDocument openApiDocument, - out OpenApiDiagnostic diagnostic, - OpenApiReaderSettings settings = null) where T : IOpenApiElement + public T? ReadFragment(JsonNode input, + OpenApiSpecVersion version, + OpenApiDocument openApiDocument, + out OpenApiDiagnostic diagnostic, + OpenApiReaderSettings? settings = null) where T : IOpenApiElement { diagnostic = new(); settings ??= new OpenApiReaderSettings(); @@ -184,7 +188,7 @@ public T ReadFragment(JsonNode input, ExtensionParsers = settings.ExtensionParsers }; - IOpenApiElement element = null; + IOpenApiElement? element = null; try { // Parse the OpenAPI element @@ -196,16 +200,19 @@ public T ReadFragment(JsonNode input, } // Validate the element - if (settings.RuleSet != null && settings.RuleSet.Rules.Any()) + if (element is not null && settings.RuleSet is not null && settings.RuleSet.Rules.Any()) { var errors = element.Validate(settings.RuleSet); - foreach (var item in errors) + if (errors is not null) { - diagnostic.Errors.Add(item); + foreach (var item in errors) + { + diagnostic.Errors.Add(item); + } } } - return (T)element; + return (T?)element; } } } diff --git a/src/Microsoft.OpenApi/Reader/OpenApiModelFactory.cs b/src/Microsoft.OpenApi/Reader/OpenApiModelFactory.cs index c30f16777..e370720e3 100644 --- a/src/Microsoft.OpenApi/Reader/OpenApiModelFactory.cs +++ b/src/Microsoft.OpenApi/Reader/OpenApiModelFactory.cs @@ -28,8 +28,8 @@ public static class OpenApiModelFactory /// The OpenAPI format. /// An OpenAPI document instance. public static ReadResult Load(MemoryStream stream, - string format = null, - OpenApiReaderSettings settings = null) + string? format = null, + OpenApiReaderSettings? settings = null) { #if NET6_0_OR_GREATER ArgumentNullException.ThrowIfNull(stream); @@ -62,7 +62,7 @@ public static ReadResult Load(MemoryStream stream, /// The OpenApiReader settings. /// Instance of newly created IOpenApiElement. /// The OpenAPI element. - public static T Load(MemoryStream input, OpenApiSpecVersion version, string format, OpenApiDocument openApiDocument, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null) where T : IOpenApiElement + public static T? Load(MemoryStream input, OpenApiSpecVersion version, string? format, OpenApiDocument openApiDocument, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings? settings = null) where T : IOpenApiElement { format ??= InspectStreamFormat(input); settings ??= DefaultReaderSettings.Value; @@ -76,7 +76,7 @@ public static T Load(MemoryStream input, OpenApiSpecVersion version, string f /// The OpenApi reader settings. /// The cancellation token /// - public static async Task LoadAsync(string url, OpenApiReaderSettings settings = null, CancellationToken token = default) + public static async Task LoadAsync(string url, OpenApiReaderSettings? settings = null, CancellationToken token = default) { settings ??= DefaultReaderSettings.Value; var (stream, format) = await RetrieveStreamAndFormatAsync(url, settings, token).ConfigureAwait(false); @@ -94,7 +94,7 @@ public static async Task LoadAsync(string url, OpenApiReaderSettings /// /// Instance of newly created IOpenApiElement. /// The OpenAPI element. - public static async Task LoadAsync(string url, OpenApiSpecVersion version, OpenApiDocument openApiDocument, OpenApiReaderSettings settings = null, CancellationToken token = default) where T : IOpenApiElement + public static async Task LoadAsync(string url, OpenApiSpecVersion version, OpenApiDocument openApiDocument, OpenApiReaderSettings? settings = null, CancellationToken token = default) where T : IOpenApiElement { settings ??= DefaultReaderSettings.Value; var (stream, format) = await RetrieveStreamAndFormatAsync(url, settings, token).ConfigureAwait(false); @@ -109,7 +109,7 @@ public static async Task LoadAsync(string url, OpenApiSpecVersion version, /// Propagates notification that operations should be cancelled. /// The Open API format /// - public static async Task LoadAsync(Stream input, string format = null, OpenApiReaderSettings settings = null, CancellationToken cancellationToken = default) + public static async Task LoadAsync(Stream input, string? format = null, OpenApiReaderSettings? settings = null, CancellationToken cancellationToken = default) { #if NET6_0_OR_GREATER ArgumentNullException.ThrowIfNull(input); @@ -155,11 +155,11 @@ public static async Task LoadAsync(Stream input, string format = nul /// /// /// - public static async Task LoadAsync(Stream input, + public static async Task LoadAsync(Stream input, OpenApiSpecVersion version, OpenApiDocument openApiDocument, - string format = null, - OpenApiReaderSettings settings = null, + string? format = null, + OpenApiReaderSettings? settings = null, CancellationToken token = default) where T : IOpenApiElement { Utils.CheckArgumentNull(openApiDocument); @@ -189,8 +189,8 @@ public static async Task LoadAsync(Stream input, /// The OpenApi reader settings. /// An OpenAPI document instance. public static ReadResult Parse(string input, - string format = null, - OpenApiReaderSettings settings = null) + string? format = null, + OpenApiReaderSettings? settings = null) { #if NET6_0_OR_GREATER ArgumentException.ThrowIfNullOrEmpty(input); @@ -216,12 +216,12 @@ public static ReadResult Parse(string input, /// The Open API format /// The OpenApi reader settings. /// An OpenAPI document instance. - public static T Parse(string input, + public static T? Parse(string input, OpenApiSpecVersion version, OpenApiDocument openApiDocument, out OpenApiDiagnostic diagnostic, - string format = null, - OpenApiReaderSettings settings = null) where T : IOpenApiElement + string? format = null, + OpenApiReaderSettings? settings = null) where T : IOpenApiElement { #if NET6_0_OR_GREATER ArgumentException.ThrowIfNullOrEmpty(input); @@ -248,22 +248,22 @@ private static async Task InternalLoadAsync(Stream input, string for // Merge diagnostics of external reference if (diagnosticExternalRefs != null) { - readResult.Diagnostic.Errors.AddRange(diagnosticExternalRefs.Errors); - readResult.Diagnostic.Warnings.AddRange(diagnosticExternalRefs.Warnings); + readResult.Diagnostic?.Errors.AddRange(diagnosticExternalRefs.Errors); + readResult.Diagnostic?.Warnings.AddRange(diagnosticExternalRefs.Warnings); } } return readResult; } - private static async Task LoadExternalRefsAsync(OpenApiDocument document, OpenApiReaderSettings settings, string format = null, CancellationToken token = default) + private static async Task LoadExternalRefsAsync(OpenApiDocument? document, OpenApiReaderSettings settings, string? format = null, CancellationToken token = default) { // Create workspace for all documents to live in. var baseUrl = settings.BaseUrl ?? new Uri(OpenApiConstants.BaseRegistryUri); var openApiWorkSpace = new OpenApiWorkspace(baseUrl); // Load this root document into the workspace - var streamLoader = new DefaultStreamLoader(settings.BaseUrl, settings.HttpClient); + var streamLoader = new DefaultStreamLoader(baseUrl, settings.HttpClient); var workspaceLoader = new OpenApiWorkspaceLoader(openApiWorkSpace, settings.CustomExternalLoader ?? streamLoader, settings); return await workspaceLoader.LoadAsync(new OpenApiReference() { ExternalResource = "/" }, document, format ?? OpenApiConstants.Json, null, token).ConfigureAwait(false); } @@ -285,21 +285,26 @@ private static ReadResult InternalLoad(MemoryStream input, string format, OpenAp return readResult; } - private static async Task<(Stream, string)> RetrieveStreamAndFormatAsync(string url, OpenApiReaderSettings settings, CancellationToken token = default) + private static async Task<(Stream, string?)> RetrieveStreamAndFormatAsync(string url, OpenApiReaderSettings settings, CancellationToken token = default) { - if (!string.IsNullOrEmpty(url)) + if (string.IsNullOrEmpty(url)) + { + throw new ArgumentException($"Parameter {nameof(url)} is null or empty. Please provide the correct path or URL to the file."); + } + else { Stream stream; - string format; + string? format; if (url.StartsWith("http", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { var response = await settings.HttpClient.GetAsync(url, token).ConfigureAwait(false); - var mediaType = response.Content.Headers.ContentType.MediaType; - var contentType = mediaType.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[0]; - format = contentType.Split('/').Last().Split('+').Last().Split('-').Last(); - // for non-standard MIME types e.g. text/x-yaml used in older libs or apps + var mediaType = response.Content.Headers.ContentType?.MediaType; + var contentType = mediaType?.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[0]; + format = contentType?.Split('/').Last().Split('+').Last().Split('-').Last(); + + // for non-standard MIME types e.g. text/x-yaml used in older libs or apps #if NETSTANDARD2_0 stream = await response.Content.ReadAsStreamAsync(); #else @@ -332,7 +337,6 @@ SecurityException or return (stream, format); } } - return (null, null); } private static string InspectInputFormat(string input) @@ -367,7 +371,7 @@ private static string InspectStreamFormat(Stream stream) }; } - private static async Task<(Stream, string)> PrepareStreamForReadingAsync(Stream input, string format, CancellationToken token = default) + private static async Task<(Stream, string)> PrepareStreamForReadingAsync(Stream input, string? format, CancellationToken token = default) { Stream preparedStream = input; diff --git a/src/Microsoft.OpenApi/Reader/OpenApiReaderSettings.cs b/src/Microsoft.OpenApi/Reader/OpenApiReaderSettings.cs index 2d24947b8..6f15fa5f6 100644 --- a/src/Microsoft.OpenApi/Reader/OpenApiReaderSettings.cs +++ b/src/Microsoft.OpenApi/Reader/OpenApiReaderSettings.cs @@ -19,7 +19,7 @@ namespace Microsoft.OpenApi.Reader public class OpenApiReaderSettings { private static readonly Lazy httpClient = new(() => new HttpClient()); - private HttpClient _httpClient; + private HttpClient? _httpClient; /// /// HttpClient to use for making requests and retrieve documents /// @@ -107,7 +107,7 @@ public Dictionary Readers /// /// Dictionary of parsers for converting extensions into strongly typed classes /// - public Dictionary> ExtensionParsers { get; set; } = new(); + public Dictionary>? ExtensionParsers { get; set; } = new(); /// /// Rules to use for validating OpenAPI specification. If none are provided a default set of rules are applied. @@ -117,12 +117,12 @@ public Dictionary Readers /// /// URL where relative references should be resolved from if the description does not contain Server definitions /// - public Uri BaseUrl { get; set; } + public Uri? BaseUrl { get; set; } /// /// Allows clients to define a custom DefaultContentType if produces array is empty /// - public List DefaultContentType { get; set; } + public List? DefaultContentType { get; set; } /// /// Function used to provide an alternative loader for accessing external references. @@ -130,7 +130,7 @@ public Dictionary Readers /// /// Default loader will attempt to dereference http(s) urls and file urls. /// - public IStreamLoader CustomExternalLoader { get; set; } + public IStreamLoader? CustomExternalLoader { get; set; } /// /// Whether to leave the object open after reading @@ -157,12 +157,13 @@ public void AddMicrosoftExtensionParsers() TryAddExtensionParser(OpenApiReservedParameterExtension.Name, static (i, _ ) => OpenApiReservedParameterExtension.Parse(i)); TryAddExtensionParser(OpenApiEnumFlagsExtension.Name, static (i, _ ) => OpenApiEnumFlagsExtension.Parse(i)); } + private void TryAddExtensionParser(string name, Func parser) { #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP || NET5_0_OR_GREATER - ExtensionParsers.TryAdd(name, parser); + ExtensionParsers?.TryAdd(name, parser); #else - if (!ExtensionParsers.ContainsKey(name)) + if (ExtensionParsers is not null && !ExtensionParsers.ContainsKey(name)) ExtensionParsers.Add(name, parser); #endif } diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/AnyFieldMapParameter.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/AnyFieldMapParameter.cs index 16456c400..7d37b3118 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/AnyFieldMapParameter.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/AnyFieldMapParameter.cs @@ -14,9 +14,9 @@ internal class AnyFieldMapParameter /// Constructor. /// public AnyFieldMapParameter( - Func propertyGetter, - Action propertySetter, - Func SchemaGetter = null) + Func propertyGetter, + Action propertySetter, + Func? SchemaGetter = null) { this.PropertyGetter = propertyGetter; this.PropertySetter = propertySetter; @@ -26,16 +26,16 @@ public AnyFieldMapParameter( /// /// Function to retrieve the value of the property. /// - public Func PropertyGetter { get; } + public Func PropertyGetter { get; } /// /// Function to set the value of the property. /// - public Action PropertySetter { get; } + public Action PropertySetter { get; } /// /// Function to get the schema to apply to the property. /// - public Func SchemaGetter { get; } + public Func? SchemaGetter { get; } } } diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/AnyListFieldMapParameter.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/AnyListFieldMapParameter.cs index fc87a548e..873f0df15 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/AnyListFieldMapParameter.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/AnyListFieldMapParameter.cs @@ -16,7 +16,7 @@ internal class AnyListFieldMapParameter public AnyListFieldMapParameter( Func> propertyGetter, Action> propertySetter, - Func SchemaGetter = null) + Func? SchemaGetter = null) { this.PropertyGetter = propertyGetter; this.PropertySetter = propertySetter; @@ -36,6 +36,6 @@ public AnyListFieldMapParameter( /// /// Function to get the schema to apply to the property. /// - public Func SchemaGetter { get; } + public Func? SchemaGetter { get; } } } diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/AnyMapFieldMapParameter.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/AnyMapFieldMapParameter.cs index 52397aed9..6a16f4e46 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/AnyMapFieldMapParameter.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/AnyMapFieldMapParameter.cs @@ -15,10 +15,10 @@ internal class AnyMapFieldMapParameter /// Constructor /// public AnyMapFieldMapParameter( - Func> propertyMapGetter, - Func propertyGetter, + Func?> propertyMapGetter, + Func propertyGetter, Action propertySetter, - Func schemaGetter) + Func schemaGetter) { this.PropertyMapGetter = propertyMapGetter; this.PropertyGetter = propertyGetter; @@ -29,12 +29,12 @@ public AnyMapFieldMapParameter( /// /// Function to retrieve the property that is a map from string to an inner element containing IOpenApiAny. /// - public Func> PropertyMapGetter { get; } + public Func?> PropertyMapGetter { get; } /// /// Function to retrieve the value of the property from an inner element. /// - public Func PropertyGetter { get; } + public Func PropertyGetter { get; } /// /// Function to set the value of the property. @@ -44,6 +44,6 @@ public AnyMapFieldMapParameter( /// /// Function to get the schema to apply to the property. /// - public Func SchemaGetter { get; } + public Func SchemaGetter { get; } } } diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/JsonPointerExtensions.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/JsonPointerExtensions.cs index b349f2d5d..28c0a48fd 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/JsonPointerExtensions.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/JsonPointerExtensions.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,7 +14,7 @@ public static class JsonPointerExtensions /// /// Finds the JSON node that corresponds to this JSON pointer based on the base Json node. /// - public static JsonNode Find(this JsonPointer currentPointer, JsonNode baseJsonNode) + public static JsonNode? Find(this JsonPointer currentPointer, JsonNode baseJsonNode) { if (currentPointer.Tokens.Length == 0) { diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/ListNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/ListNode.cs index 96235271e..4f48cbb04 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/ListNode.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/ListNode.cs @@ -25,37 +25,40 @@ public override List CreateList(Func map, Ope { if (_nodeList == null) { - throw new OpenApiReaderException($"Expected list while parsing {typeof(T).Name}", _nodeList); + throw new OpenApiReaderException($"Expected list while parsing {typeof(T).Name}"); } - return _nodeList?.Select(n => map(new MapNode(Context, n as JsonObject), hostDocument)) + 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.Select(n => Create(Context, n).CreateAny()) + 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) + public override List CreateSimpleList(Func map, OpenApiDocument openApiDocument) { if (_nodeList == null) { - throw new OpenApiReaderException($"Expected list while parsing {typeof(T).Name}", _nodeList); + throw new OpenApiReaderException($"Expected list while parsing {typeof(T).Name}"); } - return _nodeList.Select(n => map(new(Context, n), openApiDocument)).ToList(); + return _nodeList.OfType().Select(n => map(new(Context, n), openApiDocument)).ToList(); } public IEnumerator GetEnumerator() { - return _nodeList.Select(n => Create(Context, n)).ToList().GetEnumerator(); + return _nodeList.OfType().Select(n => Create(Context, n)).ToList().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs index 4988756d2..3d3ef71af 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs @@ -11,7 +11,6 @@ using System.Text.Json.Serialization; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Exceptions; -using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Models; namespace Microsoft.OpenApi.Reader.ParseNodes @@ -33,14 +32,14 @@ public MapNode(ParsingContext context, JsonNode node) : base( } _node = mapNode; - _nodes = _node.Where(static p => p.Value is not null).Select(p => new PropertyNode(Context, p.Key, p.Value)).ToList(); + _nodes = _node.Where(p => p.Value is not null).OfType>().Select(p => new PropertyNode(Context, p.Key, p.Value)).ToList(); } - public PropertyNode this[string key] + public PropertyNode? this[string key] { get { - if (_node.TryGetPropertyValue(key, out var node)) + if (_node.TryGetPropertyValue(key, out var node) && node is not null) { return new(Context, key, node); } @@ -63,7 +62,7 @@ public override Dictionary CreateMap(Func CreateSimpleMap(Func map) return nodes.ToDictionary(k => k.key, v => v.value); } - public override Dictionary> CreateArrayMap(Func map, OpenApiDocument openApiDocument) + public override Dictionary> CreateArrayMap(Func map, OpenApiDocument? openApiDocument) { var jsonMap = _node ?? throw new OpenApiReaderException($"Expected map while parsing {typeof(T).Name}", Context); @@ -117,7 +116,7 @@ public override Dictionary> CreateArrayMap(Func values = new HashSet(arrayNode.Select(item => map(new ValueNode(Context, item), openApiDocument))); + ISet values = new HashSet(arrayNode.OfType().Select(item => map(new ValueNode(Context, item), openApiDocument))); return (key, values); @@ -147,52 +146,48 @@ public override string GetRaw() return x; } - public T GetReferencedObject(ReferenceType referenceType, string referenceId, string summary = null, string description = null) - where T : IOpenApiReferenceHolder, new() + public string? GetReferencePointer() { - return new() - { - Reference = Context.VersionService.ConvertToOpenApiReference(referenceId, referenceType, summary, description) - }; - } - - public string GetReferencePointer() - { - if (!_node.TryGetPropertyValue("$ref", out JsonNode refNode)) + if (!_node.TryGetPropertyValue("$ref", out JsonNode? refNode)) { return null; } - return refNode.GetScalarValue(); + return refNode?.GetScalarValue(); } - public string GetSummaryValue() + public string? GetSummaryValue() { - if (!_node.TryGetPropertyValue("summary", out JsonNode summaryNode)) + if (!_node.TryGetPropertyValue("summary", out JsonNode? summaryNode)) { return null; } - return summaryNode.GetScalarValue(); + return summaryNode?.GetScalarValue(); } - public string GetDescriptionValue() + public string? GetDescriptionValue() { - if (!_node.TryGetPropertyValue("description", out JsonNode descriptionNode)) + if (!_node.TryGetPropertyValue("description", out JsonNode? descriptionNode)) { return null; } - return descriptionNode.GetScalarValue(); + return descriptionNode?.GetScalarValue(); } - public string GetScalarValue(ValueNode key) + public string? GetScalarValue(ValueNode key) { - var scalarNode = _node[key.GetScalarValue()] is JsonValue jsonValue - ? jsonValue - : throw new OpenApiReaderException($"Expected scalar while parsing {key.GetScalarValue()}", Context); + 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 Convert.ToString(scalarNode?.GetValue(), CultureInfo.InvariantCulture); + } + return null; } /// diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/ParseNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/ParseNode.cs index 798795350..699022193 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/ParseNode.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/ParseNode.cs @@ -43,7 +43,7 @@ public static ParseNode Create(ParsingContext context, JsonNode node) return new MapNode(context, mapNode); } - return new ValueNode(context, node as JsonValue); + return new ValueNode(context, node); } public virtual List CreateList(Func map, OpenApiDocument hostDocument) @@ -56,7 +56,7 @@ public virtual Dictionary CreateMap(Func CreateSimpleList(Func map, OpenApiDocument openApiDocument) + public virtual List CreateSimpleList(Func map, OpenApiDocument openApiDocument) { throw new OpenApiReaderException("Cannot create simple list from this type of node.", Context); } @@ -86,7 +86,7 @@ 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) + 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/RootNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/RootNode.cs index b9e49b47d..741dccd2a 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/RootNode.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/RootNode.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.Text.Json.Nodes; @@ -19,7 +19,7 @@ public RootNode( _jsonNode = jsonNode; } - public ParseNode Find(JsonPointer referencePointer) + public ParseNode? Find(JsonPointer referencePointer) { if (referencePointer.Find(_jsonNode) is not JsonNode jsonNode) { diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/ValueNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/ValueNode.cs index f83d2ba66..fd45b2adf 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/ValueNode.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/ValueNode.cs @@ -4,6 +4,7 @@ using System; using System.Globalization; using System.Text.Json.Nodes; +using System.Xml.Linq; using Microsoft.OpenApi.Exceptions; namespace Microsoft.OpenApi.Reader.ParseNodes @@ -17,14 +18,16 @@ public ValueNode(ParsingContext context, JsonNode node) : base( { if (node is not JsonValue scalarNode) { - throw new OpenApiReaderException("Expected a value.", node); + throw new OpenApiReaderException($"Expected a value while parsing at {Context.GetLocation()}."); } _node = scalarNode; } public override string GetScalarValue() { - return Convert.ToString(_node.GetValue(), CultureInfo.InvariantCulture); + var scalarValue = _node.GetValue(); + return Convert.ToString(scalarValue, CultureInfo.InvariantCulture) + ?? throw new OpenApiReaderException($"Expected a value at {Context.GetLocation()}."); } /// diff --git a/src/Microsoft.OpenApi/Reader/ParsingContext.cs b/src/Microsoft.OpenApi/Reader/ParsingContext.cs index 485686e89..93d9517b9 100644 --- a/src/Microsoft.OpenApi/Reader/ParsingContext.cs +++ b/src/Microsoft.OpenApi/Reader/ParsingContext.cs @@ -28,21 +28,21 @@ public class ParsingContext /// /// Extension parsers /// - public Dictionary> ExtensionParsers { get; set; } = + public Dictionary>? ExtensionParsers { get; set; } = new(); - internal RootNode RootNode { get; set; } + internal RootNode? RootNode { get; set; } internal List Tags { get; private set; } = new(); /// /// The base url for the document /// - public Uri BaseUrl { get; set; } + public Uri? BaseUrl { get; set; } /// /// Default content type for a response object /// - public List DefaultContentType { get; set; } + public List? DefaultContentType { get; set; } /// /// Diagnostic object that returns metadata about the parsing process. @@ -106,7 +106,7 @@ public OpenApiDocument Parse(JsonNode jsonNode) /// OpenAPI version of the fragment /// The OpenApiDocument object to which the fragment belongs, used to lookup references. /// An OpenApiDocument populated based on the passed yamlDocument - public T ParseFragment(JsonNode jsonNode, OpenApiSpecVersion version, OpenApiDocument openApiDocument) where T : IOpenApiElement + public T? ParseFragment(JsonNode jsonNode, OpenApiSpecVersion version, OpenApiDocument openApiDocument) where T : IOpenApiElement { var node = ParseNode.Create(this, jsonNode); @@ -139,20 +139,20 @@ private static string GetVersion(RootNode rootNode) { var versionNode = rootNode.Find(new("/openapi")); - if (versionNode != null) + if (versionNode is not null) { return versionNode.GetScalarValue().Replace("\"", string.Empty); } versionNode = rootNode.Find(new("/swagger")); - return versionNode?.GetScalarValue().Replace("\"", string.Empty); + return versionNode?.GetScalarValue().Replace("\"", string.Empty) ?? throw new OpenApiException("Version node not found."); } /// /// Service providing all Version specific conversion functions /// - internal IOpenApiVersionService VersionService { get; set; } + internal IOpenApiVersionService? VersionService { get; set; } /// /// End the current object. @@ -173,9 +173,9 @@ public string GetLocation() /// /// Gets the value from the temporary storage matching the given key. /// - public T GetFromTempStorage(string key, object scope = null) + public T? GetFromTempStorage(string key, object? scope = null) { - Dictionary storage; + Dictionary? storage; if (scope == null) { @@ -192,9 +192,9 @@ public T GetFromTempStorage(string key, object scope = null) /// /// Sets the temporary storage for this key and value. /// - public void SetTempStorage(string key, object value, object scope = null) + public void SetTempStorage(string key, object? value, object? scope = null) { - Dictionary storage; + Dictionary? storage; if (scope == null) { @@ -271,7 +271,7 @@ public void PopLoop(string loopid) private void ValidateRequiredFields(OpenApiDocument doc, string version) { - if ((version.is2_0() || version.is3_0()) && (doc.Paths == null)) + if ((version.is2_0() || version.is3_0()) && (doc.Paths == null) && RootNode 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()}")); diff --git a/src/Microsoft.OpenApi/Reader/ReadResult.cs b/src/Microsoft.OpenApi/Reader/ReadResult.cs index b7d3df12a..18847ad82 100644 --- a/src/Microsoft.OpenApi/Reader/ReadResult.cs +++ b/src/Microsoft.OpenApi/Reader/ReadResult.cs @@ -12,15 +12,15 @@ public class ReadResult /// /// The parsed OpenApiDocument. Null will be returned if the document could not be parsed. /// - public OpenApiDocument Document { get; set; } + public OpenApiDocument? Document { get; set; } /// /// OpenApiDiagnostic contains the Errors reported while parsing /// - public OpenApiDiagnostic Diagnostic { get; set; } + public OpenApiDiagnostic? Diagnostic { get; set; } /// /// Deconstructs the result for easier assignment on the client application. /// - public void Deconstruct(out OpenApiDocument document, out OpenApiDiagnostic diagnostic) + public void Deconstruct(out OpenApiDocument? document, out OpenApiDiagnostic? diagnostic) { document = Document; diagnostic = Diagnostic; diff --git a/src/Microsoft.OpenApi/Reader/Services/OpenApiRemoteReferenceCollector.cs b/src/Microsoft.OpenApi/Reader/Services/OpenApiRemoteReferenceCollector.cs index 8690735b8..c95955609 100644 --- a/src/Microsoft.OpenApi/Reader/Services/OpenApiRemoteReferenceCollector.cs +++ b/src/Microsoft.OpenApi/Reader/Services/OpenApiRemoteReferenceCollector.cs @@ -35,12 +35,12 @@ public override void Visit(IOpenApiReferenceHolder referenceHolder) /// /// Collect external references /// - private void AddExternalReferences(OpenApiReference reference) + private void AddExternalReferences(OpenApiReference? reference) { - if (reference is {IsExternal: true} && - !_references.ContainsKey(reference.ExternalResource)) + if (reference is {IsExternal: true} && reference.ExternalResource is {} externalResource&& + !_references.ContainsKey(externalResource)) { - _references.Add(reference.ExternalResource, reference); + _references.Add(externalResource, reference); } } } diff --git a/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs b/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs index 32090231f..75dd43512 100644 --- a/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs +++ b/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs @@ -21,16 +21,19 @@ public OpenApiWorkspaceLoader(OpenApiWorkspace workspace, IStreamLoader loader, } internal async Task LoadAsync(OpenApiReference reference, - OpenApiDocument document, - string format = null, - OpenApiDiagnostic diagnostic = null, + OpenApiDocument? document, + string? format = null, + OpenApiDiagnostic? diagnostic = null, CancellationToken cancellationToken = default) { - _workspace.AddDocumentId(reference.ExternalResource, document.BaseUri); + _workspace.AddDocumentId(reference.ExternalResource, document?.BaseUri); var version = diagnostic?.SpecificationVersion ?? OpenApiSpecVersion.OpenApi3_0; - _workspace.RegisterComponents(document); - document.Workspace = _workspace; - + if (document is not null) + { + _workspace.RegisterComponents(document); + document.Workspace = _workspace; + } + // Collect remote references by walking document var referenceCollector = new OpenApiRemoteReferenceCollector(); var collectorWalker = new OpenApiWalker(referenceCollector); @@ -43,7 +46,7 @@ internal async Task LoadAsync(OpenApiReference reference, { // If not already in workspace, load it and process references - if (!_workspace.Contains(item.ExternalResource)) + if (item.ExternalResource is not null && !_workspace.Contains(item.ExternalResource)) { var input = await _loader.LoadAsync(new(item.ExternalResource, UriKind.RelativeOrAbsolute), cancellationToken).ConfigureAwait(false); var result = await OpenApiDocument.LoadAsync(input, format, _readerSettings, cancellationToken).ConfigureAwait(false); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiContactDeserializer.cs index 00bfc2d74..9e4dcb2a9 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiContactDeserializer.cs @@ -22,7 +22,14 @@ internal static partial class OpenApiV2Deserializer }, { "url", - (o, n, t) => o.Url = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (o, n, t) => + { + var url = n.GetScalarValue(); + if (url != null) + { + o.Url = new(url, UriKind.RelativeOrAbsolute); + } + } }, { "email", @@ -40,7 +47,7 @@ public static OpenApiContact LoadContact(ParseNode node, OpenApiDocument hostDoc var mapNode = node as MapNode; var contact = new OpenApiContact(); - ParseMap(mapNode, contact, _contactFixedFields, _contactPatternFields); + ParseMap(mapNode, contact, _contactFixedFields, _contactPatternFields, doc: hostDocument); return contact; } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs index da4060721..f7cbe711a 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs @@ -70,15 +70,18 @@ internal static partial class OpenApiV2Deserializer { o.Components ??= new(); - o.Components.Parameters = n.CreateMap(LoadParameter, o); - - o.Components.RequestBodies = n.CreateMap((p, d) => - { - var parameter = LoadParameter(node: p, loadRequestBody: true, hostDocument: d); - return parameter != null ? CreateRequestBody(p.Context, parameter) : null; - }, - doc - ); + o.Components.Parameters = n.CreateMap(LoadParameter, o) + .Where(kvp => kvp.Value != null) + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value!); + + o.Components.RequestBodies = n.CreateMap((p, d) => + { + var parameter = LoadParameter(node: p, loadRequestBody: true, hostDocument: d); + return parameter != null ? CreateRequestBody(p.Context, parameter) : null; + }, + doc + ).Where(kvp => kvp.Value != null) + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value!); } }, { @@ -179,14 +182,14 @@ private static void MakeServers(IList servers, ParsingContext con { // Server Urls are always appended to Paths and Paths must start with / // so removing the slash prevents a double slash. - if (server.Url.EndsWith("/")) + if (server.Url is not null && server.Url.EndsWith("/")) { server.Url = server.Url.Substring(0, server.Url.Length - 1); } } } - private static string BuildUrl(string scheme, string host, string basePath) + private static string BuildUrl(string? scheme, string? host, string? basePath) { if (string.IsNullOrEmpty(scheme) && !string.IsNullOrEmpty(host)) { @@ -198,12 +201,15 @@ private static string BuildUrl(string scheme, string host, string basePath) #if NETSTANDARD2_1_OR_GREATER if (!String.IsNullOrEmpty(host) && host.Contains(':', StringComparison.OrdinalIgnoreCase)) #else - if (!String.IsNullOrEmpty(host) && host.Contains(':')) + if (!string.IsNullOrEmpty(host) && host is not null && host.Contains(':')) #endif { var pieces = host.Split(':'); - host = pieces.First(); - port = int.Parse(pieces.Last(), CultureInfo.InvariantCulture); + if (pieces is not null) + { + host = pieces[0]; + port = int.Parse(pieces[pieces.Count() -1], CultureInfo.InvariantCulture); + } } var uriBuilder = new UriBuilder @@ -227,7 +233,7 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode) var openApiNode = rootNode.GetMap(); - ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields); + ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, doc: openApiDoc); if (openApiDoc.Paths != null) { @@ -252,12 +258,12 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode) FixRequestBodyReferences(openApiDoc); // Register components - openApiDoc.Workspace.RegisterComponents(openApiDoc); + openApiDoc.Workspace?.RegisterComponents(openApiDoc); return openApiDoc; } - private static void ProcessResponsesMediaTypes(MapNode mapNode, IEnumerable responses, ParsingContext context) + private static void ProcessResponsesMediaTypes(MapNode mapNode, IEnumerable? responses, ParsingContext context) { if (responses != null) { @@ -280,9 +286,9 @@ private static void FixRequestBodyReferences(OpenApiDocument doc) { // Walk all unresolved parameter references // if id matches with request body Id, change type - if (doc.Components?.RequestBodies is {Count: > 0}) + if (doc.Components?.RequestBodies is { Count: > 0 }) { - var fixer = new RequestBodyReferenceFixer(doc.Components?.RequestBodies); + var fixer = new RequestBodyReferenceFixer(doc.Components.RequestBodies); var walker = new OpenApiWalker(fixer); walker.Walk(doc); } @@ -312,14 +318,15 @@ public RequestBodyReferenceFixer(IDictionary reques public override void Visit(OpenApiOperation operation) { - var body = operation.Parameters.OfType().FirstOrDefault( + var body = operation.Parameters?.OfType().FirstOrDefault( p => p.UnresolvedReference + && p.Reference?.Id != null && _requestBodies.ContainsKey(p.Reference.Id)); - - if (body != null) + var id = body?.Reference?.Id; + if (body != null && !string.IsNullOrEmpty(id) && id is not null) { - operation.Parameters.Remove(body); - operation.RequestBody = new OpenApiRequestBodyReference(body.Reference.Id, body.Reference.HostDocument); + operation.Parameters?.Remove(body); + operation.RequestBody = new OpenApiRequestBodyReference(id, body.Reference?.HostDocument); } } } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiExternalDocsDeserializer.cs index 312313585..e63e42f1b 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiExternalDocsDeserializer.cs @@ -19,11 +19,25 @@ internal static partial class OpenApiV2Deserializer { { OpenApiConstants.Description, - (o, n, _) => o.Description = n.GetScalarValue() + (o, n, _) => + { + var description = n.GetScalarValue(); + if (description != null) + { + o.Description = n.GetScalarValue(); + } + } }, { OpenApiConstants.Url, - (o, n, _) => o.Url = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (o, n, _) => + { + var url = n.GetScalarValue(); + if (url != null) + { + o.Url = new(url, UriKind.RelativeOrAbsolute); + } + } }, }; @@ -39,7 +53,7 @@ public static OpenApiExternalDocs LoadExternalDocs(ParseNode node, OpenApiDocume var externalDocs = new OpenApiExternalDocs(); - ParseMap(mapNode, externalDocs, _externalDocsFixedFields, _externalDocsPatternFields); + ParseMap(mapNode, externalDocs, _externalDocsFixedFields, _externalDocsPatternFields, doc: hostDocument); return externalDocs; } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs index e92c47231..4c156c2cc 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.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; @@ -25,7 +25,14 @@ internal static partial class OpenApiV2Deserializer }, { "type", - (o, n, _) => GetOrCreateSchema(o).Type = n.GetScalarValue().ToJsonSchemaType() + (o, n, _) => + { + var type = n.GetScalarValue(); + if (type != null) + { + GetOrCreateSchema(o).Type = type.ToJsonSchemaType(); + } + } }, { "format", @@ -37,7 +44,14 @@ internal static partial class OpenApiV2Deserializer }, { "collectionFormat", - (o, n, _) => LoadStyle(o, n.GetScalarValue()) + (o, n, _) => + { + var collectionFormat = n.GetScalarValue(); + if (collectionFormat != null) + { + LoadStyle(o, collectionFormat); + } + } }, { "default", @@ -45,7 +59,14 @@ internal static partial class OpenApiV2Deserializer }, { "maximum", - (o, n, _) => GetOrCreateSchema(o).Maximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MaxValue) + (o, n, _) => + { + var max = n.GetScalarValue(); + if (max != null) + { + GetOrCreateSchema(o).Maximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(max, decimal.MaxValue); + } + } }, { "exclusiveMaximum", @@ -53,7 +74,14 @@ internal static partial class OpenApiV2Deserializer }, { "minimum", - (o, n, _) => GetOrCreateSchema(o).Minimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MinValue) + (o, n, _) => + { + var min = n.GetScalarValue(); + if (min != null) + { + GetOrCreateSchema(o).Minimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(min, decimal.MinValue); + } + } }, { "exclusiveMinimum", @@ -61,11 +89,25 @@ internal static partial class OpenApiV2Deserializer }, { "maxLength", - (o, n, _) => GetOrCreateSchema(o).MaxLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var maxLength = n.GetScalarValue(); + if (maxLength != null) + { + GetOrCreateSchema(o).MaxLength = int.Parse(maxLength, CultureInfo.InvariantCulture); + } + } }, { "minLength", - (o, n, _) => GetOrCreateSchema(o).MinLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var minLength = n.GetScalarValue(); + if (minLength != null) + { + GetOrCreateSchema(o).MinLength = int.Parse(minLength, CultureInfo.InvariantCulture); + } + } }, { "pattern", @@ -73,19 +115,47 @@ internal static partial class OpenApiV2Deserializer }, { "maxItems", - (o, n, _) => GetOrCreateSchema(o).MaxItems = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var maxItems = n.GetScalarValue(); + if (maxItems != null) + { + GetOrCreateSchema(o).MaxItems = int.Parse(maxItems, CultureInfo.InvariantCulture); + } + } }, { "minItems", - (o, n, _) => GetOrCreateSchema(o).MinItems = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var minItems = n.GetScalarValue(); + if (minItems != null) + { + GetOrCreateSchema(o).MinItems = int.Parse(minItems, CultureInfo.InvariantCulture); + } + } }, { "uniqueItems", - (o, n, _) => GetOrCreateSchema(o).UniqueItems = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var uniqueItems = n.GetScalarValue(); + if (uniqueItems != null) + { + GetOrCreateSchema(o).UniqueItems = bool.Parse(uniqueItems); + } + } }, { "multipleOf", - (o, n, _) => GetOrCreateSchema(o).MultipleOf = decimal.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var multipleOf = n.GetScalarValue(); + if (multipleOf != null) + { + GetOrCreateSchema(o).MultipleOf = decimal.Parse(multipleOf, CultureInfo.InvariantCulture); + } + } }, { "enum", diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiInfoDeserializer.cs index 0d33e896c..7b5f850ee 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiInfoDeserializer.cs @@ -26,7 +26,14 @@ internal static partial class OpenApiV2Deserializer }, { "termsOfService", - (o, n, _) => o.TermsOfService = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (o, n, _) => + { + var terms = n.GetScalarValue(); + if (terms != null) + { + o.TermsOfService = new(terms, UriKind.RelativeOrAbsolute); + } + } }, { "contact", @@ -53,7 +60,7 @@ public static OpenApiInfo LoadInfo(ParseNode node, OpenApiDocument hostDocument) var info = new OpenApiInfo(); - ParseMap(mapNode, info, _infoFixedFields, _infoPatternFields); + ParseMap(mapNode, info, _infoFixedFields, _infoPatternFields, doc: hostDocument); return info; } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiLicenseDeserializer.cs index d4a95de89..c717f7a67 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiLicenseDeserializer.cs @@ -22,7 +22,14 @@ internal static partial class OpenApiV2Deserializer }, { "url", - (o, n, _) => o.Url = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (o, n, _) => + { + var url = n.GetScalarValue(); + if (url != null) + { + o.Url = new(url, UriKind.RelativeOrAbsolute); + } + } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiOperationDeserializer.cs index c2f6ca204..207845c7f 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiOperationDeserializer.cs @@ -49,6 +49,8 @@ internal static partial class OpenApiV2Deserializer { "parameters", (o, n, t) => o.Parameters = n.CreateList(LoadParameter, t) + .OfType() + .ToList() }, { "consumes", (_, n, doc) => { @@ -72,7 +74,14 @@ internal static partial class OpenApiV2Deserializer }, { "deprecated", - (o, n, _) => o.Deprecated = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var deprecated = n.GetScalarValue(); + if (deprecated != null) + { + o.Deprecated = bool.Parse(deprecated); + } + } }, { "security", @@ -124,10 +133,14 @@ internal static OpenApiOperation LoadOperation(ParseNode node, OpenApiDocument h } } - foreach (var response in operation.Responses.Values.OfType()) + var responses = operation.Responses; + if (responses is not null) { - ProcessProduces(node.CheckMapNode("responses"), response, node.Context); - } + foreach (var response in responses.Values.OfType()) + { + ProcessProduces(node.CheckMapNode("responses"), response, node.Context); + } + } // Reset so that it's not picked up later node.Context.SetTempStorage(TempStorageKeys.OperationProduces, null); @@ -141,7 +154,7 @@ public static OpenApiResponses LoadResponses(ParseNode node, OpenApiDocument hos var domainObject = new OpenApiResponses(); - ParseMap(mapNode, domainObject, _responsesFixedFields, _responsesPatternFields, doc:hostDocument); + ParseMap(mapNode, domainObject, _responsesFixedFields, _responsesPatternFields, doc: hostDocument); return domainObject; } @@ -152,11 +165,13 @@ private static OpenApiRequestBody CreateFormBody(ParsingContext context, List k.Name, - v => + Properties = formParameters + .Where(p => p.Name != null) + .ToDictionary( + k => k.Name!, + v => { - var schema = v.Schema.CreateShallowCopy(); + var schema = v.Schema!.CreateShallowCopy(); schema.Description = v.Description; if (schema is OpenApiSchema openApiSchema) { @@ -164,7 +179,7 @@ private static OpenApiRequestBody CreateFormBody(ParsingContext context, List(formParameters.Where(static p => p.Required).Select(static p => p.Name), StringComparer.Ordinal) + Required = new HashSet(formParameters.Where(static p => p.Required && p.Name is not null).Select(static p => p.Name!), StringComparer.Ordinal) } }; @@ -179,8 +194,14 @@ private static OpenApiRequestBody CreateFormBody(ParsingContext context, List mediaType) }; - foreach (var value in formBody.Content.Values.Where(static x => x.Schema is not null && x.Schema.Properties.Any() && x.Schema.Type == null).Select(static x => x.Schema).OfType()) + foreach (var value in formBody.Content.Values + .Where(static x => x.Schema is not null + && x.Schema.Properties is not null + && x.Schema.Properties.Any() + && x.Schema.Type == null).Select(static x => x.Schema).OfType()) + { value.Type = JsonSchemaType.Object; + } return formBody; } @@ -207,12 +228,15 @@ internal static IOpenApiRequestBody CreateRequestBody( Extensions = bodyParameter.Extensions }; - requestBody.Extensions[OpenApiConstants.BodyName] = new OpenApiAny(bodyParameter.Name); + if (requestBody.Extensions is not null && bodyParameter.Name is not null) + { + requestBody.Extensions[OpenApiConstants.BodyName] = new OpenApiAny(bodyParameter.Name); + } return requestBody; } private static OpenApiTagReference LoadTagByReference( - string tagName, OpenApiDocument hostDocument) + string tagName, OpenApiDocument? hostDocument) { return new OpenApiTagReference(tagName, hostDocument); } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs index 267ba24d7..61f3b49b1 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs @@ -35,19 +35,47 @@ internal static partial class OpenApiV2Deserializer }, { "required", - (o, n, t) => o.Required = bool.Parse(n.GetScalarValue()) + (o, n, t) => + { + var required = n.GetScalarValue(); + if (required != null) + { + o.Required = bool.Parse(required); + } + } }, { "deprecated", - (o, n, t) => o.Deprecated = bool.Parse(n.GetScalarValue()) + (o, n, t) => + { + var deprecated = n.GetScalarValue(); + if (deprecated != null) + { + o.Deprecated = bool.Parse(deprecated); + } + } }, { "allowEmptyValue", - (o, n, t) => o.AllowEmptyValue = bool.Parse(n.GetScalarValue()) + (o, n, t) => + { + var allowEmptyValue = n.GetScalarValue(); + if (allowEmptyValue != null) + { + o.AllowEmptyValue = bool.Parse(allowEmptyValue); + } + } }, { "type", - (o, n, t) => GetOrCreateSchema(o).Type = n.GetScalarValue().ToJsonSchemaType() + (o, n, t) => + { + var type = n.GetScalarValue(); + if (type != null) + { + GetOrCreateSchema(o).Type = type.ToJsonSchemaType(); + } + } }, { "items", @@ -55,7 +83,14 @@ internal static partial class OpenApiV2Deserializer }, { "collectionFormat", - (o, n, t) => LoadStyle(o, n.GetScalarValue()) + (o, n, t) => + { + var collectionFormat = n.GetScalarValue(); + if (collectionFormat != null) + { + LoadStyle(o, collectionFormat); + } + } }, { "format", @@ -63,23 +98,58 @@ internal static partial class OpenApiV2Deserializer }, { "minimum", - (o, n, t) => GetOrCreateSchema(o).Minimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MinValue) + (o, n, t) => + { + var min = n.GetScalarValue(); + if (min != null) + { + GetOrCreateSchema(o).Minimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(min, decimal.MinValue); + } + } }, { "maximum", - (o, n, t) => GetOrCreateSchema(o).Maximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MaxValue) + (o, n, t) => + { + var max = n.GetScalarValue(); + if (max != null) + { + GetOrCreateSchema(o).Maximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(max, decimal.MaxValue); + } + } }, { "maxLength", - (o, n, t) => GetOrCreateSchema(o).MaxLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, t) => + { + var maxLength = n.GetScalarValue(); + if (maxLength != null) + { + GetOrCreateSchema(o).MaxLength = int.Parse(maxLength, CultureInfo.InvariantCulture); + } + } }, { "minLength", - (o, n, t) => GetOrCreateSchema(o).MinLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, t) => + { + var minLength = n.GetScalarValue(); + if (minLength != null) + { + GetOrCreateSchema(o).MinLength = int.Parse(minLength, CultureInfo.InvariantCulture); + } + } }, { "readOnly", - (o, n, t) => GetOrCreateSchema(o).ReadOnly = bool.Parse(n.GetScalarValue()) + (o, n, t) => + { + var readOnly = n.GetScalarValue(); + if (readOnly != null) + { + GetOrCreateSchema(o).ReadOnly = bool.Parse(readOnly); + } + } }, { "default", @@ -139,7 +209,7 @@ private static void LoadStyle(OpenApiParameter p, string v) } } - private static void LoadParameterExamplesExtension(OpenApiParameter parameter, ParseNode node, OpenApiDocument hostDocument) + private static void LoadParameterExamplesExtension(OpenApiParameter parameter, ParseNode node, OpenApiDocument? hostDocument) { var examples = LoadExamplesExtension(node); node.Context.SetTempStorage(TempStorageKeys.Examples, examples, parameter); @@ -187,12 +257,12 @@ private static void ProcessIn(OpenApiParameter o, ParseNode n, OpenApiDocument h } } - public static IOpenApiParameter LoadParameter(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiParameter? LoadParameter(ParseNode node, OpenApiDocument hostDocument) { return LoadParameter(node, false, hostDocument); } - public static IOpenApiParameter LoadParameter(ParseNode node, bool loadRequestBody, OpenApiDocument hostDocument) + public static IOpenApiParameter? LoadParameter(ParseNode node, bool loadRequestBody, OpenApiDocument hostDocument) { // Reset the local variables every time this method is called. node.Context.SetTempStorage(TempStorageKeys.ParameterIsBodyOrFormData, false); @@ -226,7 +296,13 @@ public static IOpenApiParameter LoadParameter(ParseNode node, bool loadRequestBo node.Context.SetTempStorage("examples", null); } - var isBodyOrFormData = (bool)node.Context.GetFromTempStorage(TempStorageKeys.ParameterIsBodyOrFormData); + var isBodyOrFormData = false; + var paramData = node.Context.GetFromTempStorage(TempStorageKeys.ParameterIsBodyOrFormData); + if (paramData is bool boolValue) + { + isBodyOrFormData = boolValue; + } + if (isBodyOrFormData && !loadRequestBody) { return null; // Don't include Form or Body parameters when normal parameters are loaded. diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiPathItemDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiPathItemDeserializer.cs index 822f2d4ce..c0dec5050 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiPathItemDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiPathItemDeserializer.cs @@ -7,6 +7,7 @@ using System.Net.Http; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V2 @@ -58,11 +59,13 @@ private static void LoadPathParameters(OpenApiPathItem pathItem, ParseNode node, node.Context.SetTempStorage(TempStorageKeys.BodyParameter, null); node.Context.SetTempStorage(TempStorageKeys.FormParameters, null); - pathItem.Parameters = node.CreateList(LoadParameter, hostDocument); + pathItem.Parameters = node.CreateList(LoadParameter, hostDocument) + .OfType() + .ToList(); // Build request body based on information determined while parsing OpenApiOperation var bodyParameter = node.Context.GetFromTempStorage(TempStorageKeys.BodyParameter); - if (bodyParameter != null) + if (bodyParameter is not null && pathItem.Operations is not null) { var requestBody = CreateRequestBody(node.Context, bodyParameter); foreach (var opPair in pathItem.Operations.Where(x => x.Value.RequestBody is null)) @@ -82,7 +85,7 @@ private static void LoadPathParameters(OpenApiPathItem pathItem, ParseNode node, else { var formParameters = node.Context.GetFromTempStorage>(TempStorageKeys.FormParameters); - if (formParameters != null) + if (formParameters is not null && pathItem.Operations is not null) { var requestBody = CreateFormBody(node.Context, formParameters); foreach (var opPair in pathItem.Operations.Where(x => x.Value.RequestBody is null)) diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs index 514ed0b44..653208578 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs @@ -105,7 +105,7 @@ 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, ParseNode node, OpenApiDocument? hostDocument) { var examples = LoadExamplesExtension(node); node.Context.SetTempStorage(TempStorageKeys.Examples, examples, response); @@ -146,7 +146,7 @@ private static Dictionary LoadExamplesExtension(ParseNo return examples; } - private static void LoadExamples(OpenApiResponse response, ParseNode node, OpenApiDocument hostDocument) + private static void LoadExamples(OpenApiResponse response, ParseNode node, OpenApiDocument? hostDocument) { var mapNode = node.CheckMapNode("examples"); @@ -196,12 +196,14 @@ public static IOpenApiResponse LoadResponse(ParseNode node, OpenApiDocument host { property.ParseField(response, _responseFixedFields, _responsePatternFields, hostDocument); } - - foreach (var mediaType in response.Content.Values) + if (response.Content?.Values is not null) { - if (mediaType.Schema != null) + foreach (var mediaType in response.Content.Values) { - ProcessAnyFields(mapNode, mediaType, _mediaTypeAnyFields); + if (mediaType.Schema != null) + { + ProcessAnyFields(mapNode, mediaType, _mediaTypeAnyFields); + } } } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs index 87a8fdf8a..5597ed1b7 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/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.Collections.Generic; @@ -9,6 +9,7 @@ using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Models.Interfaces; using System; +using System.Linq; namespace Microsoft.OpenApi.Reader.V2 { @@ -26,11 +27,25 @@ internal static partial class OpenApiV2Deserializer }, { "multipleOf", - (o, n, _) => o.MultipleOf = decimal.Parse(n.GetScalarValue(), NumberStyles.Float, CultureInfo.InvariantCulture) + (o, n, _) => + { + var multipleOf = n.GetScalarValue(); + if (multipleOf != null) + { + o.MultipleOf = decimal.Parse(multipleOf, NumberStyles.Float, CultureInfo.InvariantCulture); + } + } }, { "maximum", - (o, n,_) => o.Maximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MaxValue) + (o, n,_) => + { + var max = n.GetScalarValue(); + if (max != null) + { + o.Maximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(max, decimal.MaxValue); + } + } }, { "exclusiveMaximum", @@ -38,7 +53,14 @@ internal static partial class OpenApiV2Deserializer }, { "minimum", - (o, n, _) => o.Minimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MinValue) + (o, n, _) => + { + var min = n.GetScalarValue(); + if (min != null) + { + o.Minimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(min, decimal.MinValue); + } + } }, { "exclusiveMinimum", @@ -46,11 +68,25 @@ internal static partial class OpenApiV2Deserializer }, { "maxLength", - (o, n, _) => o.MaxLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var maxLength = n.GetScalarValue(); + if (maxLength != null) + { + o.MaxLength = int.Parse(maxLength, CultureInfo.InvariantCulture); + } + } }, { "minLength", - (o, n, _) => o.MinLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var minLength = n.GetScalarValue(); + if (minLength != null) + { + o.MinLength = int.Parse(minLength, CultureInfo.InvariantCulture); + } + } }, { "pattern", @@ -58,27 +94,68 @@ internal static partial class OpenApiV2Deserializer }, { "maxItems", - (o, n, _) => o.MaxItems = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var maxItems = n.GetScalarValue(); + if (maxItems != null) + { + o.MaxItems = int.Parse(maxItems, CultureInfo.InvariantCulture); + } + } }, { "minItems", - (o, n, _) => o.MinItems = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var minItems = n.GetScalarValue(); + if (minItems != null) + { + o.MinItems = int.Parse(minItems, CultureInfo.InvariantCulture); + } + } }, { "uniqueItems", - (o, n, _) => o.UniqueItems = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var uniqueItems = n.GetScalarValue(); + if (uniqueItems != null) + { + o.UniqueItems = bool.Parse(uniqueItems); + } + } }, { "maxProperties", - (o, n, _) => o.MaxProperties = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var maxProps = n.GetScalarValue(); + if (maxProps != null) + { + o.MaxProperties = int.Parse(maxProps, CultureInfo.InvariantCulture); + } + } }, { "minProperties", - (o, n, _) => o.MinProperties = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var minProps = n.GetScalarValue(); + if (minProps != null) + { + o.MinProperties = int.Parse(minProps, CultureInfo.InvariantCulture); + } + } }, { "required", - (o, n, doc) => o.Required = new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc)) + (o, n, doc) => + { + o.Required = new HashSet( + n.CreateSimpleList((n2, p) => + n2.GetScalarValue(), doc) + .Where(s => s != null)!); + } }, { "enum", @@ -87,7 +164,14 @@ internal static partial class OpenApiV2Deserializer { "type", - (o, n, _) => o.Type = n.GetScalarValue().ToJsonSchemaType() + (o, n, _) => + { + var type = n.GetScalarValue(); + if (type != null) + { + o.Type = type.ToJsonSchemaType(); + } + } }, { "allOf", @@ -106,7 +190,11 @@ internal static partial class OpenApiV2Deserializer { if (n is ValueNode) { - o.AdditionalPropertiesAllowed = bool.Parse(n.GetScalarValue()); + var value = n.GetScalarValue(); + if (value is not null) + { + o.AdditionalPropertiesAllowed = bool.Parse(value); + } } else { @@ -137,7 +225,14 @@ internal static partial class OpenApiV2Deserializer }, { "readOnly", - (o, n, _) => o.ReadOnly = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var readOnly = n.GetScalarValue(); + if (readOnly is not null) + { + o.ReadOnly = bool.Parse(readOnly); + } + } }, { "xml", diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecurityRequirementDeserializer.cs index 7b47ff6c5..1fec679df 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecurityRequirementDeserializer.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Models.References; @@ -26,7 +27,9 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, hostDocument, property.Name); - var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue(), hostDocument); + var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue(), hostDocument) + .OfType() + .ToList(); if (scheme != null) { @@ -44,7 +47,7 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, } private static OpenApiSecuritySchemeReference LoadSecuritySchemeByReference( - OpenApiDocument openApiDocument, + OpenApiDocument? openApiDocument, string schemeName) { return new OpenApiSecuritySchemeReference(schemeName, openApiDocument); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs index 0dc329f43..af9ff89f9 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.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.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models.Interfaces; @@ -15,9 +16,9 @@ namespace Microsoft.OpenApi.Reader.V2 /// internal static partial class OpenApiV2Deserializer { - private static string _flowValue; + private static string? _flowValue; - private static OpenApiOAuthFlow _flow; + private static OpenApiOAuthFlow? _flow; private static readonly FixedFieldMap _securitySchemeFixedFields = new() @@ -50,7 +51,7 @@ internal static partial class OpenApiV2Deserializer }, {"description", (o, n, _) => o.Description = n.GetScalarValue()}, {"name", (o, n, _) => o.Name = n.GetScalarValue()}, - {"in", (o, n, _) => + {"in", (o, n, _) => { if (!n.GetScalarValue().TryGetEnumFromDisplayName(n.Context, out var _in)) { @@ -64,14 +65,36 @@ internal static partial class OpenApiV2Deserializer }, { "authorizationUrl", - (_, n, _) => _flow.AuthorizationUrl = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (_, n, _) => + { + var scalarValue = n.GetScalarValue(); + if (_flow is not null && scalarValue is not null) + { + _flow.AuthorizationUrl = new(scalarValue, UriKind.RelativeOrAbsolute); + } + } }, { "tokenUrl", - (_, n, _) => _flow.TokenUrl = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (_, n, _) => + { + var scalarValue = n.GetScalarValue(); + if (_flow is not null && scalarValue is not null) + { + _flow.TokenUrl = new(scalarValue, UriKind.RelativeOrAbsolute); + } + } }, { - "scopes", (_, n, _) => _flow.Scopes = n.CreateSimpleMap(LoadString) + "scopes", (_, n, _) => + { + if (_flow is not null) + { + _flow.Scopes = n.CreateSimpleMap(LoadString) + .Where(kv => kv.Value != null) + .ToDictionary(kv => kv.Key, kv => kv.Value!); + } + } } }; diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs index 83505670d..dc347615e 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs @@ -20,12 +20,12 @@ namespace Microsoft.OpenApi.Reader.V2 internal static partial class OpenApiV2Deserializer { private static void ParseMap( - MapNode mapNode, + MapNode? mapNode, T domainObject, FixedFieldMap fixedFieldMap, PatternFieldMap patternFieldMap, - List requiredFields = null, - OpenApiDocument doc = null) + OpenApiDocument doc, + List? requiredFields = null) { if (mapNode == null) { @@ -80,7 +80,7 @@ public static JsonNode LoadAny(ParseNode node, OpenApiDocument hostDocument) private static IOpenApiExtension LoadExtension(string name, ParseNode node) { - if (node.Context.ExtensionParsers.TryGetValue(name, out var parser)) + if (node.Context.ExtensionParsers is not null && node.Context.ExtensionParsers.TryGetValue(name, out var parser)) { return parser(node.CreateAny(), OpenApiSpecVersion.OpenApi2_0); } @@ -90,18 +90,18 @@ private static IOpenApiExtension LoadExtension(string name, ParseNode node) } } - private static string LoadString(ParseNode node) + private static string? LoadString(ParseNode node) { return node.GetScalarValue(); } - private static (string, string) GetReferenceIdAndExternalResource(string pointer) + private static (string, string?) GetReferenceIdAndExternalResource(string pointer) { var refSegments = pointer.Split('/'); - var refId = refSegments.Last(); - var isExternalResource = !refSegments.First().StartsWith("#", StringComparison.OrdinalIgnoreCase); + var refId = refSegments[refSegments.Count() -1]; + var isExternalResource = !refSegments[0].StartsWith("#", StringComparison.OrdinalIgnoreCase); - string externalResource = isExternalResource ? $"{refSegments.First()}/{refSegments[1].TrimEnd('#')}" : null; + string? externalResource = isExternalResource ? $"{refSegments[0]}/{refSegments[1].TrimEnd('#')}" : null; return (refId, externalResource); } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs index c4186bb25..d92e9ce78 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs @@ -29,7 +29,7 @@ public OpenApiV2VersionService(OpenApiDiagnostic diagnostic) Diagnostic = diagnostic; } - private readonly Dictionary> _loaders = new() + private readonly Dictionary> _loaders = new() { [typeof(OpenApiAny)] = OpenApiV2Deserializer.LoadAny, [typeof(OpenApiContact)] = OpenApiV2Deserializer.LoadContact, @@ -50,173 +50,18 @@ public OpenApiV2VersionService(OpenApiDiagnostic diagnostic) [typeof(OpenApiXml)] = OpenApiV2Deserializer.LoadXml }; - private static OpenApiReference ParseLocalReference(string localReference) - { - if (string.IsNullOrWhiteSpace(localReference)) - { - throw new ArgumentException( - string.Format( - SRResource.ArgumentNullOrWhiteSpace, - nameof(localReference))); - } - - var segments = localReference.Split('/'); - - // /definitions/Pet/... - if (segments.Length >= 3) - { - var referenceType = ParseReferenceType(segments[1]); - var id = localReference.Substring( - segments[0].Length + "/".Length + segments[1].Length + "/".Length); - - return new() { Type = referenceType, Id = id }; - } - - throw new OpenApiException( - string.Format( - SRResource.ReferenceHasInvalidFormat, - localReference)); - } - - private static ReferenceType ParseReferenceType(string referenceTypeName) - { - switch (referenceTypeName) - { - case "definitions": - return ReferenceType.Schema; - - case "parameters": - return ReferenceType.Parameter; - - case "responses": - return ReferenceType.Response; - - case "headers": - return ReferenceType.Header; - - case "tags": - return ReferenceType.Tag; - - case "securityDefinitions": - return ReferenceType.SecurityScheme; - - default: - throw new OpenApiReaderException($"Unknown reference type '{referenceTypeName}'"); - } - } - - private static ReferenceType GetReferenceTypeV2FromName(string referenceType) - { - switch (referenceType) - { - case "definitions": - return ReferenceType.Schema; - - case "parameters": - return ReferenceType.Parameter; - - case "responses": - return ReferenceType.Response; - - case "tags": - return ReferenceType.Tag; - - case "securityDefinitions": - return ReferenceType.SecurityScheme; - - default: - throw new ArgumentException(); - } - } - - /// - /// Parse the string to a object. - /// - public OpenApiReference ConvertToOpenApiReference(string reference, ReferenceType? type, string summary = null, string description = null) - { - if (!string.IsNullOrWhiteSpace(reference)) - { - var segments = reference.Split('#'); - if (segments.Length == 1) - { - // Either this is an external reference as an entire file - // or a simple string-style reference for tag and security scheme. - if (type == null) - { - // "$ref": "Pet.json" - return new() - { - ExternalResource = segments[0] - }; - } - - if (type is ReferenceType.Tag or ReferenceType.SecurityScheme) - { - return new() - { - Type = type, - Id = reference - }; - } - } - else if (segments.Length == 2) - { - if (reference.StartsWith("#", StringComparison.OrdinalIgnoreCase)) - { - // "$ref": "#/definitions/Pet" - try - { - return ParseLocalReference(segments[1]); - } - catch (OpenApiException ex) - { - Diagnostic.Errors.Add(new(ex)); - return null; - } - } - - // Where fragments point into a non-OpenAPI document, the id will be the complete fragment identifier - var id = segments[1]; - // $ref: externalSource.yaml#/Pet - if (id.StartsWith("/definitions/", StringComparison.Ordinal)) - { - var localSegments = id.Split('/'); - var referencedType = GetReferenceTypeV2FromName(localSegments[1]); - if (type == null) - { - type = referencedType; - } - else - { - if (type != referencedType) - { - throw new OpenApiException("Referenced type mismatch"); - } - } - id = localSegments[2]; - } - - // $ref: externalSource.yaml#/Pet - return new() - { - ExternalResource = segments[0], - Type = type, - Id = id - }; - } - } - - throw new OpenApiException(string.Format(SRResource.ReferenceHasInvalidFormat, reference)); - } - public OpenApiDocument LoadDocument(RootNode rootNode) { return OpenApiV2Deserializer.LoadOpenApi(rootNode); } - public T LoadElement(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement + public T? LoadElement(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement { - return (T)_loaders[typeof(T)](node, doc); + if (_loaders.TryGetValue(typeof(T), out var loader) && loader(node, doc) is T result) + { + return result; + } + return default; } /// diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiXmlDeserializer.cs index 38acf840d..a1eb9ba9f 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiXmlDeserializer.cs @@ -24,9 +24,10 @@ internal static partial class OpenApiV2Deserializer { "namespace", (o, n, _) => { - if (Uri.IsWellFormedUriString(n.GetScalarValue(), UriKind.Absolute)) + var scalarValue = n.GetScalarValue(); + if (Uri.IsWellFormedUriString(scalarValue, UriKind.Absolute) && scalarValue is not null) { - o.Namespace = new(n.GetScalarValue(), UriKind.Absolute); + o.Namespace = new(scalarValue, UriKind.Absolute); } else { @@ -40,11 +41,25 @@ internal static partial class OpenApiV2Deserializer }, { "attribute", - (o, n, _) => o.Attribute = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var attribute = n.GetScalarValue(); + if (attribute is not null) + { + o.Attribute = bool.Parse(attribute); + } + } }, { "wrapped", - (o, n, _) => o.Wrapped = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var wrapped = n.GetScalarValue(); + if (wrapped is not null) + { + o.Wrapped = bool.Parse(wrapped); + } + } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiContactDeserializer.cs index 7eab275c8..21b11b794 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiContactDeserializer.cs @@ -26,7 +26,14 @@ internal static partial class OpenApiV3Deserializer }, { "url", - (o, n, _) => o.Url = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (o, n, t) => + { + var url = n.GetScalarValue(); + if (url != null) + { + o.Url = new(url, UriKind.RelativeOrAbsolute); + } + } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs index 5f9db648e..1493283c0 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader.ParseNodes; @@ -21,7 +22,7 @@ internal static partial class OpenApiV3Deserializer }, { "mapping", - (o, n, _) => o.Mapping = n.CreateSimpleMap(LoadString) + (o, n, _) => o.Mapping = n.CreateSimpleMap(LoadString).Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value!) } }; diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs index 044542d21..6e5fb952b 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs @@ -46,7 +46,7 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode) ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, openApiDoc); // Register components - openApiDoc.Workspace.RegisterComponents(openApiDoc); + openApiDoc.Workspace?.RegisterComponents(openApiDoc); return openApiDoc; } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs index 2d324745d..c2d88936f 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs @@ -37,11 +37,25 @@ internal static partial class OpenApiV3Deserializer }, { "explode", - (o, n, _) => o.Explode = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var explode = n.GetScalarValue(); + if (explode != null) + { + o.Explode = bool.Parse(explode); + } + } }, { "allowedReserved", - (o, n, _) => o.AllowReserved = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var allowReserved = n.GetScalarValue(); + if (allowReserved != null) + { + o.AllowReserved = bool.Parse(allowReserved); + } + } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiExternalDocsDeserializer.cs index 0d8c25b05..7f357b947 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiExternalDocsDeserializer.cs @@ -24,8 +24,15 @@ internal static partial class OpenApiV3Deserializer }, { "url", - (o, n, _) => o.Url = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) - }, + (o, n, _) => + { + var url = n.GetScalarValue(); + if (url != null) + { + o.Url = new(url, UriKind.RelativeOrAbsolute); + } + } + } }; private static readonly PatternFieldMap _externalDocsPatternFields = diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs index 94350d429..4b3318357 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs @@ -24,19 +24,47 @@ internal static partial class OpenApiV3Deserializer }, { "required", - (o, n, _) => o.Required = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var required = n.GetScalarValue(); + if (required != null) + { + o.Required = bool.Parse(required); + } + } }, { "deprecated", - (o, n, _) => o.Deprecated = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var deprecated = n.GetScalarValue(); + if (deprecated != null) + { + o.Deprecated = bool.Parse(deprecated); + } + } }, { "allowEmptyValue", - (o, n, _) => o.AllowEmptyValue = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var allowEmptyVal = n.GetScalarValue(); + if (allowEmptyVal != null) + { + o.AllowEmptyValue = bool.Parse(allowEmptyVal); + } + } }, { "allowReserved", - (o, n, _) => o.AllowReserved = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var allowReserved = n.GetScalarValue(); + if (allowReserved != null) + { + o.AllowReserved = bool.Parse(allowReserved); + } + } }, { "style", @@ -51,7 +79,14 @@ internal static partial class OpenApiV3Deserializer }, { "explode", - (o, n, _) => o.Explode = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var explode = n.GetScalarValue(); + if (explode != null) + { + o.Explode = bool.Parse(explode); + } + } }, { "schema", diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiInfoDeserializer.cs index 48979439d..2686e5d1a 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiInfoDeserializer.cs @@ -30,7 +30,14 @@ internal static partial class OpenApiV3Deserializer }, { "termsOfService", - (o, n, _) => o.TermsOfService = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (o, n, _) => + { + var terms = n.GetScalarValue(); + if (terms != null) + { + o.TermsOfService = new(terms, UriKind.RelativeOrAbsolute); + } + } }, { "contact", diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiLicenseDeserializer.cs index 4ecdce151..eaf9ba24f 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiLicenseDeserializer.cs @@ -22,7 +22,14 @@ internal static partial class OpenApiV3Deserializer }, { "url", - (o, n, _) => o.Url = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (o, n, _) => + { + var url = n.GetScalarValue(); + if (url != null) + { + o.Url = new(url, UriKind.RelativeOrAbsolute); + } + } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs index 6fd96b38d..b0e99bd44 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs @@ -54,8 +54,8 @@ internal static partial class OpenApiV3Deserializer }; private static readonly AnyMapFieldMap _mediaTypeAnyMapOpenApiExampleFields = - new() - { + new() + { { OpenApiConstants.Examples, new( diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowDeserializer.cs index d60cf0aa5..1771f1407 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowDeserializer.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. using System; +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader.ParseNodes; @@ -19,17 +20,38 @@ internal static partial class OpenApiV3Deserializer { { "authorizationUrl", - (o, n, _) => o.AuthorizationUrl = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (o, n, _) => + { + var url = n.GetScalarValue(); + if (url != null) + { + o.AuthorizationUrl = new(url, UriKind.RelativeOrAbsolute); + } + } }, { "tokenUrl", - (o, n, _) => o.TokenUrl = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (o, n, _) => + { + var url = n.GetScalarValue(); + if (url != null) + { + o.TokenUrl = new(url, UriKind.RelativeOrAbsolute); + } + } }, { "refreshUrl", - (o, n, _) => o.RefreshUrl = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (o, n, _) => + { + var url = n.GetScalarValue(); + if (url != null) + { + o.RefreshUrl = new(url, UriKind.RelativeOrAbsolute); + } + } }, - {"scopes", (o, n, _) => o.Scopes = n.CreateSimpleMap(LoadString)} + {"scopes", (o, n, _) => o.Scopes = n.CreateSimpleMap(LoadString).Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value!)} }; private static readonly PatternFieldMap _oAuthFlowPatternFields = diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiOperationDeserializer.cs index 9fca4d14b..00fdeb3ee 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiOperationDeserializer.cs @@ -61,7 +61,14 @@ internal static partial class OpenApiV3Deserializer }, { "deprecated", - (o, n, _) => o.Deprecated = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var deprecated = n.GetScalarValue(); + if (deprecated != null) + { + o.Deprecated = bool.Parse(deprecated); + } + } }, { "security", @@ -91,7 +98,7 @@ internal static OpenApiOperation LoadOperation(ParseNode node, OpenApiDocument h } private static OpenApiTagReference LoadTagByReference( - string tagName, OpenApiDocument hostDocument) + string tagName, OpenApiDocument? hostDocument) { return new OpenApiTagReference(tagName, hostDocument); } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs index 7d2c5074b..33e67b953 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs @@ -39,19 +39,47 @@ internal static partial class OpenApiV3Deserializer }, { "required", - (o, n, _) => o.Required = bool.Parse(n.GetScalarValue()) + (o, n, t) => + { + var required = n.GetScalarValue(); + if (required != null) + { + o.Required = bool.Parse(required); + } + } }, { "deprecated", - (o, n, _) => o.Deprecated = bool.Parse(n.GetScalarValue()) + (o, n, t) => + { + var deprecated = n.GetScalarValue(); + if (deprecated != null) + { + o.Deprecated = bool.Parse(deprecated); + } + } }, { "allowEmptyValue", - (o, n, _) => o.AllowEmptyValue = bool.Parse(n.GetScalarValue()) + (o, n, t) => + { + var allowEmptyValue = n.GetScalarValue(); + if (allowEmptyValue != null) + { + o.AllowEmptyValue = bool.Parse(allowEmptyValue); + } + } }, { "allowReserved", - (o, n, _) => o.AllowReserved = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var allowReserved = n.GetScalarValue(); + if (allowReserved != null) + { + o.AllowReserved = bool.Parse(allowReserved); + } + } }, { "style", @@ -66,7 +94,14 @@ internal static partial class OpenApiV3Deserializer }, { "explode", - (o, n, _) => o.Explode = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var explode = n.GetScalarValue(); + if (explode != null) + { + o.Explode = bool.Parse(explode); + } + } }, { "schema", diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiRequestBodyDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiRequestBodyDeserializer.cs index ac007d813..339ca437e 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiRequestBodyDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiRequestBodyDeserializer.cs @@ -29,7 +29,14 @@ internal static partial class OpenApiV3Deserializer }, { "required", - (o, n, _) => o.Required = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var required = n.GetScalarValue(); + if (required != null) + { + o.Required = bool.Parse(required); + } + } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs index 2cc13484f..464d6b1b5 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/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 Microsoft.OpenApi.Extensions; @@ -9,6 +9,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; namespace Microsoft.OpenApi.Reader.V3 { @@ -26,11 +27,25 @@ internal static partial class OpenApiV3Deserializer }, { "multipleOf", - (o, n, _) => o.MultipleOf = decimal.Parse(n.GetScalarValue(), NumberStyles.Float, CultureInfo.InvariantCulture) + (o, n, _) => + { + var multipleOf = n.GetScalarValue(); + if (multipleOf != null) + { + o.MultipleOf = decimal.Parse(multipleOf, NumberStyles.Float, CultureInfo.InvariantCulture); + } + } }, { "maximum", - (o, n, _) => o.Maximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MaxValue) + (o, n,_) => + { + var max = n.GetScalarValue(); + if (max != null) + { + o.Maximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(max, decimal.MaxValue); + } + } }, { "exclusiveMaximum", @@ -38,7 +53,14 @@ internal static partial class OpenApiV3Deserializer }, { "minimum", - (o, n, _) => o.Minimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MinValue) + (o, n, _) => + { + var min = n.GetScalarValue(); + if (min != null) + { + o.Minimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(min, decimal.MinValue); + } + } }, { "exclusiveMinimum", @@ -46,11 +68,25 @@ internal static partial class OpenApiV3Deserializer }, { "maxLength", - (o, n, _) => o.MaxLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var maxLength = n.GetScalarValue(); + if (maxLength != null) + { + o.MaxLength = int.Parse(maxLength, CultureInfo.InvariantCulture); + } + } }, { "minLength", - (o, n, _) => o.MinLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var minLength = n.GetScalarValue(); + if (minLength != null) + { + o.MinLength = int.Parse(minLength, CultureInfo.InvariantCulture); + } + } }, { "pattern", @@ -58,27 +94,62 @@ internal static partial class OpenApiV3Deserializer }, { "maxItems", - (o, n, _) => o.MaxItems = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var maxItems = n.GetScalarValue(); + if (maxItems != null) + { + o.MaxItems = int.Parse(maxItems, CultureInfo.InvariantCulture); + } + } }, { "minItems", - (o, n, _) => o.MinItems = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var minItems = n.GetScalarValue(); + if (minItems != null) + { + o.MinItems = int.Parse(minItems, CultureInfo.InvariantCulture); + } + } }, { "uniqueItems", - (o, n, _) => o.UniqueItems = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var uniqueItems = n.GetScalarValue(); + if (uniqueItems != null) + { + o.UniqueItems = bool.Parse(uniqueItems); + } + } }, { "maxProperties", - (o, n, _) => o.MaxProperties = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var maxProps = n.GetScalarValue(); + if (maxProps != null) + { + o.MaxProperties = int.Parse(maxProps, CultureInfo.InvariantCulture); + } + } }, { "minProperties", - (o, n, _) => o.MinProperties = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var minProps = n.GetScalarValue(); + if (minProps != null) + { + o.MinProperties = int.Parse(minProps, CultureInfo.InvariantCulture); + } + } }, { "required", - (o, n, doc) => o.Required = new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc)) + (o, n, doc) => o.Required = new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc).Where(s => s != null)) }, { "enum", @@ -87,7 +158,7 @@ internal static partial class OpenApiV3Deserializer { "type", (o, n, _) => { - var type = n.GetScalarValue().ToJsonSchemaType(); + var type = n.GetScalarValue()?.ToJsonSchemaType(); // so we don't loose the value from nullable if (o.Type.HasValue) o.Type |= type; @@ -124,7 +195,11 @@ internal static partial class OpenApiV3Deserializer { if (n is ValueNode) { - o.AdditionalPropertiesAllowed = bool.Parse(n.GetScalarValue()); + var value = n.GetScalarValue(); + if (value is not null) + { + o.AdditionalPropertiesAllowed = bool.Parse(value); + } } else { @@ -163,11 +238,25 @@ internal static partial class OpenApiV3Deserializer }, { "readOnly", - (o, n, _) => o.ReadOnly = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var readOnly = n.GetScalarValue(); + if (readOnly != null) + { + o.ReadOnly = bool.Parse(readOnly); + } + } }, { "writeOnly", - (o, n, _) => o.WriteOnly = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var writeOnly = n.GetScalarValue(); + if (writeOnly != null) + { + o.WriteOnly = bool.Parse(writeOnly); + } + } }, { "xml", @@ -183,7 +272,14 @@ internal static partial class OpenApiV3Deserializer }, { "deprecated", - (o, n, _) => o.Deprecated = bool.Parse(n.GetScalarValue()) + (o, n, t) => + { + var deprecated = n.GetScalarValue(); + if (deprecated != null) + { + o.Deprecated = bool.Parse(deprecated); + } + } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecurityRequirementDeserializer.cs index 030f2ef34..018ca26ab 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecurityRequirementDeserializer.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Models.References; @@ -24,7 +25,9 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, { var scheme = LoadSecuritySchemeByReference(hostDocument, property.Name); - var scopes = property.Value.CreateSimpleList((value, p) => value.GetScalarValue(), hostDocument); + var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue(), hostDocument) + .OfType() + .ToList(); if (scheme != null) { @@ -41,7 +44,7 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, } private static OpenApiSecuritySchemeReference LoadSecuritySchemeByReference( - OpenApiDocument openApiDocument, + OpenApiDocument? openApiDocument, string schemeName) { return new OpenApiSecuritySchemeReference(schemeName, openApiDocument); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs index 993279f1e..b01ece23f 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.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; @@ -59,7 +59,14 @@ internal static partial class OpenApiV3Deserializer }, { "openIdConnectUrl", - (o, n, _) => o.OpenIdConnectUrl = new(n.GetScalarValue(), UriKind.RelativeOrAbsolute) + (o, n, _) => + { + var connectUrl = n.GetScalarValue(); + if (connectUrl != null) + { + o.OpenIdConnectUrl = new(connectUrl, UriKind.RelativeOrAbsolute); + } + } }, { "flows", diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiServerVariableDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiServerVariableDeserializer.cs index 3579a40b7..5e9642df6 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiServerVariableDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiServerVariableDeserializer.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. using System; +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader.ParseNodes; @@ -19,7 +20,7 @@ internal static partial class OpenApiV3Deserializer { { "enum", - (o, n, doc) => o.Enum = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc) + (o, n, doc) => o.Enum = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc).OfType().ToList() }, { "default", diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs index 45559a029..29eb3db70 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs @@ -21,7 +21,7 @@ namespace Microsoft.OpenApi.Reader.V3 internal static partial class OpenApiV3Deserializer { private static void ParseMap( - MapNode mapNode, + MapNode? mapNode, T domainObject, FixedFieldMap fixedFieldMap, PatternFieldMap patternFieldMap, @@ -72,38 +72,6 @@ private static void ProcessAnyFields( } } - private static void ProcessAnyListFields( - MapNode mapNode, - T domainObject, - AnyListFieldMap anyListFieldMap) - { - foreach (var anyListFieldName in anyListFieldMap.Keys.ToList()) - { - try - { - var newProperty = new List(); - - mapNode.Context.StartObject(anyListFieldName); - - foreach (var propertyElement in anyListFieldMap[anyListFieldName].PropertyGetter(domainObject)) - { - newProperty.Add(propertyElement); - } - - anyListFieldMap[anyListFieldName].PropertySetter(domainObject, newProperty); - } - catch (OpenApiException exception) - { - exception.Pointer = mapNode.Context.GetLocation(); - mapNode.Context.Diagnostic.Errors.Add(new(exception)); - } - finally - { - mapNode.Context.EndObject(); - } - } - } - private static void ProcessAnyMapFields( MapNode mapNode, T domainObject, @@ -114,18 +82,23 @@ private static void ProcessAnyMapFields( try { mapNode.Context.StartObject(anyMapFieldName); - - foreach (var propertyMapElement in anyMapFieldMap[anyMapFieldName].PropertyMapGetter(domainObject)) + var mapElements = anyMapFieldMap[anyMapFieldName].PropertyMapGetter(domainObject); + if (mapElements is not null) { - mapNode.Context.StartObject(propertyMapElement.Key); - - if (propertyMapElement.Value != null) + foreach (var propertyMapElement in mapElements) { - var any = anyMapFieldMap[anyMapFieldName].PropertyGetter(propertyMapElement.Value); - - anyMapFieldMap[anyMapFieldName].PropertySetter(propertyMapElement.Value, any); + mapNode.Context.StartObject(propertyMapElement.Key); + + if (propertyMapElement.Value != null) + { + var any = anyMapFieldMap[anyMapFieldName].PropertyGetter(propertyMapElement.Value); + if (any is not null) + { + anyMapFieldMap[anyMapFieldName].PropertySetter(propertyMapElement.Value, any); + } + } } - } + } } catch (OpenApiException exception) { @@ -139,12 +112,6 @@ private static void ProcessAnyMapFields( } } - private static RuntimeExpression LoadRuntimeExpression(ParseNode node) - { - var value = node.GetScalarValue(); - return RuntimeExpression.Build(value); - } - private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(ParseNode node) { var value = node.GetScalarValue(); @@ -171,7 +138,7 @@ public static OpenApiAny LoadAny(ParseNode node, OpenApiDocument hostDocument) private static IOpenApiExtension LoadExtension(string name, ParseNode node) { - if (node.Context.ExtensionParsers.TryGetValue(name, out var parser) && parser( + if (node.Context.ExtensionParsers is not null && node.Context.ExtensionParsers.TryGetValue(name, out var parser) && parser( node.CreateAny(), OpenApiSpecVersion.OpenApi3_0) is { } result) { return result; @@ -182,23 +149,22 @@ private static IOpenApiExtension LoadExtension(string name, ParseNode node) } } - private static string LoadString(ParseNode node) + private static string? LoadString(ParseNode node) { return node.GetScalarValue(); } - private static (string, string) GetReferenceIdAndExternalResource(string pointer) + private static (string, string?) GetReferenceIdAndExternalResource(string pointer) { var refSegments = pointer.Split('/'); - var refId = refSegments.Last(); - var isExternalResource = !refSegments.First().StartsWith("#", StringComparison.OrdinalIgnoreCase); - - string externalResource = null; + var refId = refSegments[refSegments.Count() -1]; + var isExternalResource = !refSegments[0].StartsWith("#", StringComparison.OrdinalIgnoreCase); + + string? externalResource = null; if (isExternalResource) { externalResource = pointer.Split('#')[0].TrimEnd('#'); } - return (refId, externalResource); } } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs index 612c59dfb..d568b327c 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs @@ -65,111 +65,6 @@ public OpenApiV3VersionService(OpenApiDiagnostic diagnostic) [typeof(OpenApiXml)] = OpenApiV3Deserializer.LoadXml }; - /// - /// Parse the string to a object. - /// - /// The URL of the reference - /// The type of object referenced based on the context of the reference - /// - /// - public OpenApiReference ConvertToOpenApiReference( - string reference, - ReferenceType? type, - string summary = null, - string description = null) - { - if (!string.IsNullOrWhiteSpace(reference)) - { - var segments = reference.Split('#'); - if (segments.Length == 1) - { - if (type is ReferenceType.Tag or ReferenceType.SecurityScheme) - { - return new() - { - Type = type, - Id = reference - }; - } - - // Either this is an external reference as an entire file - // or a simple string-style reference for tag and security scheme. - return new() - { - Type = type, - ExternalResource = segments[0] - }; - } - else if (segments.Length == 2) - { - if (reference.StartsWith("#", StringComparison.OrdinalIgnoreCase)) - { - // "$ref": "#/components/schemas/Pet" - try - { - return ParseLocalReference(segments[1]); - } - catch (OpenApiException ex) - { - Diagnostic.Errors.Add(new(ex)); - } - } - // Where fragments point into a non-OpenAPI document, the id will be the complete fragment identifier - var id = segments[1]; - var isFragment = false; - - // $ref: externalSource.yaml#/Pet - if (id.StartsWith("/components/", StringComparison.Ordinal)) - { - var localSegments = segments[1].Split('/'); - localSegments[2].TryGetEnumFromDisplayName(out var referencedType); - if (type == null) - { - type = referencedType; - } - else - { - if (type != referencedType) - { - throw new OpenApiException("Referenced type mismatch"); - } - } - id = localSegments[3]; - } - else if (id.StartsWith("/paths/", StringComparison.Ordinal)) - { - var localSegments = segments[1].Split(_pathSeparator, StringSplitOptions.RemoveEmptyEntries); - if (localSegments.Length == 2) - { - // The reference of a path may contain JSON escape character ~1 for the forward-slash character, replace this otherwise - // the reference cannot be resolved. - id = localSegments[1].Replace("~1", "/"); - } - else - { - throw new OpenApiException("Referenced Path mismatch"); - } - } - else - { - isFragment = true; - } - - var openApiReference = new OpenApiReference - { - ExternalResource = segments[0], - Type = type, - Id = id, - IsFragment = isFragment, - }; - - return openApiReference; - } - } - - throw new OpenApiException(string.Format(SRResource.ReferenceHasInvalidFormat, reference)); - } - public OpenApiDocument LoadDocument(RootNode rootNode) { return OpenApiV3Deserializer.LoadOpenApi(rootNode); @@ -181,7 +76,7 @@ public T LoadElement(ParseNode node, OpenApiDocument doc) where T : IOpenApiE } /// - public string GetReferenceScalarValues(MapNode mapNode, string scalarValue) + public string? GetReferenceScalarValues(MapNode mapNode, string scalarValue) { if (mapNode.Any(static x => !"$ref".Equals(x.Name, StringComparison.OrdinalIgnoreCase)) && mapNode @@ -193,36 +88,6 @@ public string GetReferenceScalarValues(MapNode mapNode, string scalarValue) } return null; - } - - private OpenApiReference ParseLocalReference(string localReference) - { - if (string.IsNullOrWhiteSpace(localReference)) - { - throw new ArgumentException(string.Format(SRResource.ArgumentNullOrWhiteSpace, nameof(localReference))); - } - - var segments = localReference.Split('/'); - - if (segments.Length == 4 && segments[1] == "components") // /components/{type}/pet - { - segments[2].TryGetEnumFromDisplayName(out var referenceType); - var refId = segments[3]; - if (segments[2] == "pathItems") - { - refId = "/" + segments[3]; - } - - var parsedReference = new OpenApiReference - { - Type = referenceType, - Id = refId - }; - - return parsedReference; - } - - throw new OpenApiException(string.Format(SRResource.ReferenceHasInvalidFormat, localReference)); - } + } } } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiXmlDeserializer.cs index 43245338d..e6bc2c836 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiXmlDeserializer.cs @@ -22,7 +22,14 @@ internal static partial class OpenApiV3Deserializer }, { "namespace", - (o, n, _) => o.Namespace = new(n.GetScalarValue(), UriKind.Absolute) + (o, n, _) => + { + var value = n.GetScalarValue(); + if (value != null) + { + o.Namespace = new(value, UriKind.Absolute); + } + } }, { "prefix", @@ -30,11 +37,25 @@ internal static partial class OpenApiV3Deserializer }, { "attribute", - (o, n, _) => o.Attribute = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var attribute = n.GetScalarValue(); + if (attribute is not null) + { + o.Attribute = bool.Parse(attribute); + } + } }, { "wrapped", - (o, n, _) => o.Wrapped = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var wrapped = n.GetScalarValue(); + if (wrapped is not null) + { + o.Wrapped = bool.Parse(wrapped); + } + } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiContactDeserializer.cs index be487e434..138eafe70 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiContactDeserializer.cs @@ -26,9 +26,14 @@ internal static partial class OpenApiV31Deserializer } }, { - "url", (o, n, _) => + "url", + (o, n, t) => { - o.Url = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); + var url = n.GetScalarValue(); + if (url != null) + { + o.Url = new(url, UriKind.RelativeOrAbsolute); + } } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiDiscriminatorDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiDiscriminatorDeserializer.cs index 0302149f6..e94f408d2 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.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader.ParseNodes; @@ -23,7 +24,7 @@ internal static partial class OpenApiV31Deserializer { "mapping", (o, n, _) => { - o.Mapping = n.CreateSimpleMap(LoadString); + o.Mapping = n.CreateSimpleMap(LoadString).Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value!); } } }; diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs index ae95f58e4..0abe92234 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs @@ -44,7 +44,7 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode) ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields, openApiDoc); // Register components - openApiDoc.Workspace.RegisterComponents(openApiDoc); + openApiDoc.Workspace?.RegisterComponents(openApiDoc); return openApiDoc; } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs index d571a42d0..5272f6495 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs @@ -38,13 +38,21 @@ internal static partial class OpenApiV31Deserializer { "explode", (o, n, _) => { - o.Explode = bool.Parse(n.GetScalarValue()); + var explode = n.GetScalarValue(); + if (explode is not null) + { + o.Explode = bool.Parse(explode); + } } }, { "allowedReserved", (o, n, _) => { - o.AllowReserved = bool.Parse(n.GetScalarValue()); + var allowReserved = n.GetScalarValue(); + if (allowReserved is not null) + { + o.AllowReserved = bool.Parse(allowReserved); + } } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiExternalDocsDeserializer.cs index a5b06efff..75d9c89a1 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiExternalDocsDeserializer.cs @@ -22,9 +22,14 @@ internal static partial class OpenApiV31Deserializer } }, { - "url", (o, n, _) => + "url", + (o, n, t) => { - o.Url = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); + var url = n.GetScalarValue(); + if (url != null) + { + o.Url = new(url, UriKind.RelativeOrAbsolute); + } } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs index 2c23c70a4..3c01a56a2 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs @@ -22,27 +22,47 @@ internal static partial class OpenApiV31Deserializer } }, { - "required", (o, n, _) => + "required", + (o, n, _) => { - o.Required = bool.Parse(n.GetScalarValue()); + var required = n.GetScalarValue(); + if (required != null) + { + o.Required = bool.Parse(required); + } } }, { - "deprecated", (o, n, _) => + "deprecated", + (o, n, _) => { - o.Deprecated = bool.Parse(n.GetScalarValue()); + var deprecated = n.GetScalarValue(); + if (deprecated != null) + { + o.Deprecated = bool.Parse(deprecated); + } } }, { - "allowEmptyValue", (o, n, _) => + "allowEmptyValue", + (o, n, _) => { - o.AllowEmptyValue = bool.Parse(n.GetScalarValue()); + var allowEmptyVal = n.GetScalarValue(); + if (allowEmptyVal != null) + { + o.AllowEmptyValue = bool.Parse(allowEmptyVal); + } } }, { - "allowReserved", (o, n, _) => + "allowReserved", + (o, n, _) => { - o.AllowReserved = bool.Parse(n.GetScalarValue()); + var allowReserved = n.GetScalarValue(); + if (allowReserved != null) + { + o.AllowReserved = bool.Parse(allowReserved); + } } }, { @@ -56,9 +76,14 @@ internal static partial class OpenApiV31Deserializer } }, { - "explode", (o, n, _) => + "explode", + (o, n, _) => { - o.Explode = bool.Parse(n.GetScalarValue()); + var explode = n.GetScalarValue(); + if (explode != null) + { + o.Explode = bool.Parse(explode); + } } }, { diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiInfoDeserializer.cs index 86597b421..49a700683 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiInfoDeserializer.cs @@ -38,9 +38,14 @@ internal static partial class OpenApiV31Deserializer } }, { - "termsOfService", (o, n, _) => + "termsOfService", + (o, n, _) => { - o.TermsOfService = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); + var terms = n.GetScalarValue(); + if (terms != null) + { + o.TermsOfService = new(terms, UriKind.RelativeOrAbsolute); + } } }, { diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiLicenseDeserializer.cs index 7ef705095..1f874d21e 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiLicenseDeserializer.cs @@ -26,11 +26,16 @@ internal static partial class OpenApiV31Deserializer } }, { - "url", (o, n, _) => + "url", + (o, n, _) => { - o.Url = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); + var url = n.GetScalarValue(); + if (url != null) + { + o.Url = new(url, UriKind.RelativeOrAbsolute); + } } - }, + } }; private static readonly PatternFieldMap _licensePatternFields = new() diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowDeserializer.cs index 3efc3ef5a..ab5f29350 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.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader.ParseNodes; @@ -15,24 +16,39 @@ internal static partial class OpenApiV31Deserializer new() { { - "authorizationUrl", (o, n, _) => + "authorizationUrl", + (o, n, _) => { - o.AuthorizationUrl = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); + var url = n.GetScalarValue(); + if (url != null) + { + o.AuthorizationUrl = new(url, UriKind.RelativeOrAbsolute); + } } }, { - "tokenUrl", (o, n, _) => + "tokenUrl", + (o, n, _) => { - o.TokenUrl = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); + var url = n.GetScalarValue(); + if (url != null) + { + o.TokenUrl = new(url, UriKind.RelativeOrAbsolute); + } } }, { - "refreshUrl", (o, n, _) => + "refreshUrl", + (o, n, _) => { - o.RefreshUrl = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); + var url = n.GetScalarValue(); + if (url != null) + { + o.RefreshUrl = new(url, UriKind.RelativeOrAbsolute); + } } }, - {"scopes", (o, n, _) => o.Scopes = n.CreateSimpleMap(LoadString)} + {"scopes", (o, n, _) => o.Scopes = n.CreateSimpleMap(LoadString).Where(kv => kv.Value is not null).ToDictionary(kv => kv.Key, kv => kv.Value!)} }; private static readonly PatternFieldMap _oAuthFlowPatternFields = diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiOperationDeserializer.cs index d969cca36..cf0b4856c 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiOperationDeserializer.cs @@ -73,9 +73,14 @@ internal static partial class OpenApiV31Deserializer } }, { - "deprecated", (o, n, _) => + "deprecated", + (o, n, _) => { - o.Deprecated = bool.Parse(n.GetScalarValue()); + var deprecated = n.GetScalarValue(); + if (deprecated != null) + { + o.Deprecated = bool.Parse(deprecated); + } } }, { @@ -109,7 +114,7 @@ internal static OpenApiOperation LoadOperation(ParseNode node, OpenApiDocument h return operation; } - private static OpenApiTagReference LoadTagByReference(string tagName, OpenApiDocument hostDocument) + private static OpenApiTagReference LoadTagByReference(string tagName, OpenApiDocument? hostDocument) { var tagObject = new OpenApiTagReference(tagName, hostDocument); return tagObject; diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs index 35e1308cb..eae4e4993 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs @@ -39,27 +39,47 @@ internal static partial class OpenApiV31Deserializer } }, { - "required", (o, n, _) => + "required", + (o, n, t) => { - o.Required = bool.Parse(n.GetScalarValue()); + var required = n.GetScalarValue(); + if (required != null) + { + o.Required = bool.Parse(required); + } } }, { - "deprecated", (o, n, _) => + "deprecated", + (o, n, t) => { - o.Deprecated = bool.Parse(n.GetScalarValue()); + var deprecated = n.GetScalarValue(); + if (deprecated != null) + { + o.Deprecated = bool.Parse(deprecated); + } } }, { - "allowEmptyValue", (o, n, _) => + "allowEmptyValue", + (o, n, t) => { - o.AllowEmptyValue = bool.Parse(n.GetScalarValue()); + var allowEmptyValue = n.GetScalarValue(); + if (allowEmptyValue != null) + { + o.AllowEmptyValue = bool.Parse(allowEmptyValue); + } } }, { - "allowReserved", (o, n, _) => + "allowReserved", + (o, n, _) => { - o.AllowReserved = bool.Parse(n.GetScalarValue()); + var allowReserved = n.GetScalarValue(); + if (allowReserved != null) + { + o.AllowReserved = bool.Parse(allowReserved); + } } }, { @@ -75,7 +95,11 @@ internal static partial class OpenApiV31Deserializer { "explode", (o, n, _) => { - o.Explode = bool.Parse(n.GetScalarValue()); + var explode = n.GetScalarValue(); + if (explode != null) + { + o.Explode = bool.Parse(explode); + } } }, { diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiRequestBodyDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiRequestBodyDeserializer.cs index fe786aa44..ef08b1b2b 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiRequestBodyDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiRequestBodyDeserializer.cs @@ -31,7 +31,11 @@ internal static partial class OpenApiV31Deserializer { "required", (o, n, _) => { - o.Required = bool.Parse(n.GetScalarValue()); + var required = n.GetScalarValue(); + if (required != null) + { + o.Required = bool.Parse(required); + } } }, }; diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs index 4be2a4b5d..717a6e68f 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs @@ -35,7 +35,7 @@ internal static partial class OpenApiV31Deserializer }, { "$vocabulary", - (o, n, _) => o.Vocabulary = n.CreateSimpleMap(LoadBool) + (o, n, _) => o.Vocabulary = n.CreateSimpleMap(LoadBool).ToDictionary(kvp => kvp.Key, kvp => kvp.Value ?? false) }, { "$dynamicRef", @@ -49,13 +49,27 @@ internal static partial class OpenApiV31Deserializer "$defs", (o, n, t) => o.Definitions = n.CreateMap(LoadSchema, t) }, - { + { "multipleOf", - (o, n, _) => o.MultipleOf = decimal.Parse(n.GetScalarValue(), NumberStyles.Float, CultureInfo.InvariantCulture) + (o, n, _) => + { + var multipleOf = n.GetScalarValue(); + if (multipleOf != null) + { + o.MultipleOf = decimal.Parse(multipleOf, NumberStyles.Float, CultureInfo.InvariantCulture); + } + } }, { "maximum", - (o, n, _) => o.Maximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MaxValue) + (o, n,_) => + { + var max = n.GetScalarValue(); + if (max != null) + { + o.Maximum = ParserHelper.ParseDecimalWithFallbackOnOverflow(max, decimal.MaxValue); + } + } }, { "exclusiveMaximum", @@ -63,7 +77,14 @@ internal static partial class OpenApiV31Deserializer }, { "minimum", - (o, n, _) => o.Minimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(n.GetScalarValue(), decimal.MinValue) + (o, n, _) => + { + var min = n.GetScalarValue(); + if (min != null) + { + o.Minimum = ParserHelper.ParseDecimalWithFallbackOnOverflow(min, decimal.MinValue); + } + } }, { "exclusiveMinimum", @@ -71,11 +92,25 @@ internal static partial class OpenApiV31Deserializer }, { "maxLength", - (o, n, _) => o.MaxLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var maxLength = n.GetScalarValue(); + if (maxLength != null) + { + o.MaxLength = int.Parse(maxLength, CultureInfo.InvariantCulture); + } + } }, { "minLength", - (o, n, _) => o.MinLength = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var minLength = n.GetScalarValue(); + if (minLength != null) + { + o.MinLength = int.Parse(minLength, CultureInfo.InvariantCulture); + } + } }, { "pattern", @@ -83,31 +118,73 @@ internal static partial class OpenApiV31Deserializer }, { "maxItems", - (o, n, _) => o.MaxItems = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var maxItems = n.GetScalarValue(); + if (maxItems != null) + { + o.MaxItems = int.Parse(maxItems, CultureInfo.InvariantCulture); + } + } }, { "minItems", - (o, n, _) => o.MinItems = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var minItems = n.GetScalarValue(); + if (minItems != null) + { + o.MinItems = int.Parse(minItems, CultureInfo.InvariantCulture); + } + } }, { "uniqueItems", - (o, n, _) => o.UniqueItems = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var uniqueItems = n.GetScalarValue(); + if (uniqueItems != null) + { + o.UniqueItems = bool.Parse(uniqueItems); + } + } }, { "unevaluatedProperties", - (o, n, _) => o.UnevaluatedProperties = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var unevaluatedProps = n.GetScalarValue(); + if (unevaluatedProps != null) + { + o.UnevaluatedProperties = bool.Parse(unevaluatedProps); + } + } }, { "maxProperties", - (o, n, _) => o.MaxProperties = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var maxProps = n.GetScalarValue(); + if (maxProps != null) + { + o.MaxProperties = int.Parse(maxProps, CultureInfo.InvariantCulture); + } + } }, { "minProperties", - (o, n, _) => o.MinProperties = int.Parse(n.GetScalarValue(), CultureInfo.InvariantCulture) + (o, n, _) => + { + var minProps = n.GetScalarValue(); + if (minProps != null) + { + o.MinProperties = int.Parse(minProps, CultureInfo.InvariantCulture); + } + } }, { "required", - (o, n, doc) => o.Required = new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc)) + (o, n, doc) => o.Required = new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue(), doc).Where(s => s != null)) }, { "enum", @@ -119,7 +196,7 @@ internal static partial class OpenApiV31Deserializer { if (n is ValueNode) { - o.Type = n.GetScalarValue().ToJsonSchemaType(); + o.Type = n.GetScalarValue()?.ToJsonSchemaType(); } else { @@ -127,8 +204,11 @@ internal static partial class OpenApiV31Deserializer JsonSchemaType combinedType = 0; foreach(var type in list) { - var schemaType = type.ToJsonSchemaType(); - combinedType |= schemaType; + if (type is not null) + { + var schemaType = type.ToJsonSchemaType(); + combinedType |= schemaType; + } } o.Type = combinedType; } @@ -171,7 +251,11 @@ internal static partial class OpenApiV31Deserializer { if (n is ValueNode) { - o.AdditionalPropertiesAllowed = bool.Parse(n.GetScalarValue()); + var value = n.GetScalarValue(); + if (value is not null) + { + o.AdditionalPropertiesAllowed = bool.Parse(value); + } } else { @@ -195,10 +279,14 @@ internal static partial class OpenApiV31Deserializer "nullable", (o, n, _) => { - var nullable = bool.Parse(n.GetScalarValue()); - if (nullable) // if nullable, convert type into an array of type(s) and null + var value = n.GetScalarValue(); + if (value is not null) { - o.Type |= JsonSchemaType.Null; + var nullable = bool.Parse(value); + if (nullable) // if nullable, convert type into an array of type(s) and null + { + o.Type |= JsonSchemaType.Null; + } } } }, @@ -208,11 +296,25 @@ internal static partial class OpenApiV31Deserializer }, { "readOnly", - (o, n, _) => o.ReadOnly = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var readOnly = n.GetScalarValue(); + if (readOnly != null) + { + o.ReadOnly = bool.Parse(readOnly); + } + } }, { "writeOnly", - (o, n, _) => o.WriteOnly = bool.Parse(n.GetScalarValue()) + (o, n, _) => + { + var writeOnly = n.GetScalarValue(); + if (writeOnly != null) + { + o.WriteOnly = bool.Parse(writeOnly); + } + } }, { "xml", @@ -232,7 +334,14 @@ internal static partial class OpenApiV31Deserializer }, { "deprecated", - (o, n, _) => o.Deprecated = bool.Parse(n.GetScalarValue()) + (o, n, t) => + { + var deprecated = n.GetScalarValue(); + if (deprecated != null) + { + o.Deprecated = bool.Parse(deprecated); + } + } }, { "dependentRequired", @@ -273,13 +382,13 @@ public static IOpenApiSchema LoadSchema(ParseNode node, OpenApiDocument hostDocu { propertyNode.ParseField(schema, _openApiSchemaFixedFields, _openApiSchemaPatternFields, hostDocument); } - else + else if (schema.UnrecognizedKeywords is not null && propertyNode.JsonNode is not null) { schema.UnrecognizedKeywords[propertyNode.Name] = propertyNode.JsonNode; } } - if (schema.Extensions.ContainsKey(OpenApiConstants.NullableExtension)) + if (schema.Extensions is not null && schema.Extensions.ContainsKey(OpenApiConstants.NullableExtension)) { var type = schema.Type; schema.Type = type | JsonSchemaType.Null; diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecurityRequirementDeserializer.cs index cddb97699..fda3551d2 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecurityRequirementDeserializer.cs @@ -1,6 +1,7 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Models.References; @@ -24,8 +25,9 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, { var scheme = LoadSecuritySchemeByReference(property.Name, hostDocument); - var scopes = property.Value.CreateSimpleList((value, p) => value.GetScalarValue(), hostDocument); - + var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue(), hostDocument) + .OfType() + .ToList(); if (scheme != null) { securityRequirement.Add(scheme, scopes); @@ -40,7 +42,7 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, return securityRequirement; } - private static OpenApiSecuritySchemeReference LoadSecuritySchemeByReference(string schemeName, OpenApiDocument hostDocument) + private static OpenApiSecuritySchemeReference LoadSecuritySchemeByReference(string schemeName, OpenApiDocument? hostDocument) { return new OpenApiSecuritySchemeReference(schemeName, hostDocument); } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs index 2189f1179..54136f669 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.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; @@ -66,7 +66,11 @@ internal static partial class OpenApiV31Deserializer { "openIdConnectUrl", (o, n, _) => { - o.OpenIdConnectUrl = new Uri(n.GetScalarValue(), UriKind.RelativeOrAbsolute); + var connectUrl = n.GetScalarValue(); + if (connectUrl != null) + { + o.OpenIdConnectUrl = new(connectUrl, UriKind.RelativeOrAbsolute); + } } }, { diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiServerVariableDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiServerVariableDeserializer.cs index a3aaa141a..46181ed62 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiServerVariableDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiServerVariableDeserializer.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. using System; +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader.ParseNodes; @@ -20,7 +21,7 @@ internal static partial class OpenApiV31Deserializer { "enum", (o, n, doc) => { - o.Enum = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc); + o.Enum = n.CreateSimpleList((s, p) => s.GetScalarValue(), doc).OfType().ToList(); } }, { diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs index f9f3b168e..4ecb26bf7 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs @@ -20,11 +20,11 @@ namespace Microsoft.OpenApi.Reader.V31 internal static partial class OpenApiV31Deserializer { private static void ParseMap( - MapNode mapNode, + MapNode? mapNode, T domainObject, - FixedFieldMap fixedFieldMap, + FixedFieldMap fixedFieldMap, PatternFieldMap patternFieldMap, - OpenApiDocument doc = null) + OpenApiDocument doc) { if (mapNode == null) { @@ -92,8 +92,10 @@ private static void ProcessAnyMapFields( if (propertyMapElement.Value != null) { var any = anyMapFieldMap[anyMapFieldName].PropertyGetter(propertyMapElement.Value); - - anyMapFieldMap[anyMapFieldName].PropertySetter(propertyMapElement.Value, any); + if (any is not null) + { + anyMapFieldMap[anyMapFieldName].PropertySetter(propertyMapElement.Value, any); + } } } } @@ -135,22 +137,23 @@ public static JsonNode LoadAny(ParseNode node, OpenApiDocument hostDocument) private static IOpenApiExtension LoadExtension(string name, ParseNode node) { - return node.Context.ExtensionParsers.TryGetValue(name, out var parser) + return node.Context.ExtensionParsers is not null && node.Context.ExtensionParsers.TryGetValue(name, out var parser) ? parser(node.CreateAny(), OpenApiSpecVersion.OpenApi3_1) : new OpenApiAny(node.CreateAny()); } - private static string LoadString(ParseNode node) + private static string? LoadString(ParseNode node) { return node.GetScalarValue(); } - private static bool LoadBool(ParseNode node) + private static bool? LoadBool(ParseNode node) { - return bool.Parse(node.GetScalarValue()); + var value = node.GetScalarValue(); + return value is not null ? bool.Parse(value) : null; } - private static (string, string) GetReferenceIdAndExternalResource(string pointer) + private static (string, string?) GetReferenceIdAndExternalResource(string pointer) { /* Check whether the reference pointer is a URL * (id keyword allows you to supply a URL for the schema as a target for referencing) @@ -159,10 +162,10 @@ private static (string, string) GetReferenceIdAndExternalResource(string pointer * E.g. $ref: '#/components/schemas/pet' */ var refSegments = pointer.Split('/'); - string refId = !pointer.Contains('#') ? pointer : refSegments.Last(); + string refId = !pointer.Contains('#') ? pointer : refSegments[refSegments.Count()-1]; - var isExternalResource = !refSegments.First().StartsWith("#", StringComparison.OrdinalIgnoreCase); - string externalResource = null; + var isExternalResource = !refSegments[0].StartsWith("#", StringComparison.OrdinalIgnoreCase); + string? externalResource = null; if (isExternalResource && pointer.Contains('#')) { externalResource = pointer.Split('#')[0].TrimEnd('#'); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs index bfaa82051..bb6cac930 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs @@ -64,95 +64,6 @@ public OpenApiV31VersionService(OpenApiDiagnostic diagnostic) [typeof(OpenApiXml)] = OpenApiV31Deserializer.LoadXml }; - /// - /// Parse the string to a object. - /// - /// The URL of the reference - /// The type of object refefenced based on the context of the reference - /// The summary of the reference - /// A reference description - public OpenApiReference ConvertToOpenApiReference( - string reference, - ReferenceType? type, - string summary = null, - string description = null) - { - if (!string.IsNullOrWhiteSpace(reference)) - { - var segments = reference.Split('#'); - if (segments.Length == 1) - { - if (type == ReferenceType.Tag || type == ReferenceType.SecurityScheme) - { - return new OpenApiReference - { - Summary = summary, - Description = description, - Type = type, - Id = reference - }; - } - - // Either this is an external reference as an entire file - // or a simple string-style reference for tag and security scheme. - return new OpenApiReference - { - Summary = summary, - Description = description, - Type = type, - ExternalResource = segments[0] - }; - } - else if (segments.Length == 2) - { - if (reference.StartsWith("#", StringComparison.OrdinalIgnoreCase)) - { - // "$ref": "#/components/schemas/Pet" - try - { - return ParseLocalReference(segments[1], summary, description); - } - catch (OpenApiException ex) - { - Diagnostic.Errors.Add(new OpenApiError(ex)); - return null; - } - } - // Where fragments point into a non-OpenAPI document, the id will be the complete fragment identifier - string id = segments[1]; - // $ref: externalSource.yaml#/Pet - if (id.StartsWith("/components/", StringComparison.Ordinal)) - { - var localSegments = segments[1].Split('/'); - localSegments[2].TryGetEnumFromDisplayName(out var referencedType); - if (type == null) - { - type = referencedType; - } - else - { - if (type != referencedType) - { - throw new OpenApiException("Referenced type mismatch"); - } - } - id = localSegments[3]; - } - - return new OpenApiReference - { - Summary = summary, - Description = description, - ExternalResource = segments[0], - Type = type, - Id = id - }; - } - } - - throw new OpenApiException(string.Format(SRResource.ReferenceHasInvalidFormat, reference)); - } - public OpenApiDocument LoadDocument(RootNode rootNode) { return OpenApiV31Deserializer.LoadOpenApi(rootNode); @@ -164,7 +75,7 @@ public T LoadElement(ParseNode node, OpenApiDocument doc) where T : IOpenApiE } /// - public string GetReferenceScalarValues(MapNode mapNode, string scalarValue) + public string? GetReferenceScalarValues(MapNode mapNode, string scalarValue) { if (mapNode.Any(static x => !"$ref".Equals(x.Name, StringComparison.OrdinalIgnoreCase))) { @@ -176,37 +87,5 @@ public string GetReferenceScalarValues(MapNode mapNode, string scalarValue) return null; } - - private OpenApiReference ParseLocalReference(string localReference, string summary = null, string description = null) - { - if (string.IsNullOrWhiteSpace(localReference)) - { - throw new ArgumentException(string.Format(SRResource.ArgumentNullOrWhiteSpace, nameof(localReference))); - } - - var segments = localReference.Split('/'); - - if (segments.Length == 4 && segments[1] == "components") // /components/{type}/pet - { - segments[2].TryGetEnumFromDisplayName(out var referenceType); - var refId = segments[3]; - if (segments[2] == "pathItems") - { - refId = "/" + segments[3]; - } - - var parsedReference = new OpenApiReference - { - Summary = summary, - Description = description, - Type = referenceType, - Id = refId - }; - - return parsedReference; - } - - throw new OpenApiException(string.Format(SRResource.ReferenceHasInvalidFormat, localReference)); - } } } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiXmlDeserializer.cs index 0f821e9d2..c2776c52a 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiXmlDeserializer.cs @@ -23,29 +23,42 @@ internal static partial class OpenApiV31Deserializer } }, { - "namespace", (o, n, _) => + "namespace", + (o, n, _) => { - o.Namespace = new Uri(n.GetScalarValue(), UriKind.Absolute); + var value = n.GetScalarValue(); + if (value != null) + { + o.Namespace = new(value, UriKind.Absolute); + } } }, { - "prefix", (o, n, _) => - { - o.Prefix = n.GetScalarValue(); - } + "prefix", + (o, n, _) => o.Prefix = n.GetScalarValue() }, { - "attribute", (o, n, _) => + "attribute", + (o, n, _) => { - o.Attribute = bool.Parse(n.GetScalarValue()); + var attribute = n.GetScalarValue(); + if (attribute is not null) + { + o.Attribute = bool.Parse(attribute); + } } }, { - "wrapped", (o, n, _) => + "wrapped", + (o, n, _) => { - o.Wrapped = bool.Parse(n.GetScalarValue()); + var wrapped = n.GetScalarValue(); + if (wrapped is not null) + { + o.Wrapped = bool.Parse(wrapped); + } } - }, + } }; private static readonly PatternFieldMap _xmlPatternFields = diff --git a/src/Microsoft.OpenApi/Services/CopyReferences.cs b/src/Microsoft.OpenApi/Services/CopyReferences.cs index ab0ad8e31..6874b3f8d 100644 --- a/src/Microsoft.OpenApi/Services/CopyReferences.cs +++ b/src/Microsoft.OpenApi/Services/CopyReferences.cs @@ -19,61 +19,61 @@ public override void Visit(IOpenApiReferenceHolder referenceHolder) switch (referenceHolder) { case OpenApiSchemaReference openApiSchemaReference: - AddSchemaToComponents(openApiSchemaReference.Target, openApiSchemaReference.Reference.Id); + AddSchemaToComponents(openApiSchemaReference.Target, openApiSchemaReference.Reference?.Id); break; case OpenApiSchema schema: AddSchemaToComponents(schema); break; case OpenApiParameterReference openApiParameterReference: - AddParameterToComponents(openApiParameterReference.Target, openApiParameterReference.Reference.Id); + AddParameterToComponents(openApiParameterReference.Target, openApiParameterReference.Reference?.Id); break; case OpenApiParameter parameter: AddParameterToComponents(parameter); break; case OpenApiResponseReference openApiResponseReference: - AddResponseToComponents(openApiResponseReference.Target, openApiResponseReference.Reference.Id); + AddResponseToComponents(openApiResponseReference.Target, openApiResponseReference.Reference?.Id); break; case OpenApiResponse response: AddResponseToComponents(response); break; case OpenApiRequestBodyReference openApiRequestBodyReference: - AddRequestBodyToComponents(openApiRequestBodyReference.Target, openApiRequestBodyReference.Reference.Id); + AddRequestBodyToComponents(openApiRequestBodyReference.Target, openApiRequestBodyReference.Reference?.Id); break; case OpenApiRequestBody requestBody: AddRequestBodyToComponents(requestBody); break; case OpenApiExampleReference openApiExampleReference: - AddExampleToComponents(openApiExampleReference.Target, openApiExampleReference.Reference.Id); + AddExampleToComponents(openApiExampleReference.Target, openApiExampleReference.Reference?.Id); break; case OpenApiExample example: AddExampleToComponents(example); break; case OpenApiHeaderReference openApiHeaderReference: - AddHeaderToComponents(openApiHeaderReference.Target, openApiHeaderReference.Reference.Id); + AddHeaderToComponents(openApiHeaderReference.Target, openApiHeaderReference.Reference?.Id); break; case OpenApiHeader header: AddHeaderToComponents(header); break; case OpenApiCallbackReference openApiCallbackReference: - AddCallbackToComponents(openApiCallbackReference.Target, openApiCallbackReference.Reference.Id); + AddCallbackToComponents(openApiCallbackReference.Target, openApiCallbackReference.Reference?.Id); break; case OpenApiCallback callback: AddCallbackToComponents(callback); break; case OpenApiLinkReference openApiLinkReference: - AddLinkToComponents(openApiLinkReference.Target, openApiLinkReference.Reference.Id); + AddLinkToComponents(openApiLinkReference.Target, openApiLinkReference.Reference?.Id); break; case OpenApiLink link: AddLinkToComponents(link); break; case OpenApiSecuritySchemeReference openApiSecuritySchemeReference: - AddSecuritySchemeToComponents(openApiSecuritySchemeReference.Target, openApiSecuritySchemeReference.Reference.Id); + AddSecuritySchemeToComponents(openApiSecuritySchemeReference.Target, openApiSecuritySchemeReference.Reference?.Id); break; case OpenApiSecurityScheme securityScheme: AddSecuritySchemeToComponents(securityScheme); break; case OpenApiPathItemReference openApiPathItemReference: - AddPathItemToComponents(openApiPathItemReference.Target, openApiPathItemReference.Reference.Id); + AddPathItemToComponents(openApiPathItemReference.Target, openApiPathItemReference.Reference?.Id); break; case OpenApiPathItem pathItem: AddPathItemToComponents(pathItem); @@ -85,94 +85,94 @@ public override void Visit(IOpenApiReferenceHolder referenceHolder) base.Visit(referenceHolder); } - private void AddSchemaToComponents(IOpenApiSchema schema, string referenceId = null) + private void AddSchemaToComponents(IOpenApiSchema? schema, string? referenceId = null) { EnsureComponentsExist(); EnsureSchemasExist(); - if (!Components.Schemas.ContainsKey(referenceId)) + if (Components.Schemas is not null && referenceId is not null && schema is not null && !Components.Schemas.ContainsKey(referenceId)) { Components.Schemas.Add(referenceId, schema); } } - private void AddParameterToComponents(IOpenApiParameter parameter, string referenceId = null) + private void AddParameterToComponents(IOpenApiParameter? parameter, string? referenceId = null) { EnsureComponentsExist(); EnsureParametersExist(); - if (!Components.Parameters.ContainsKey(referenceId)) + if (Components.Parameters is not null && parameter is not null && referenceId is not null && !Components.Parameters.ContainsKey(referenceId)) { Components.Parameters.Add(referenceId, parameter); } } - private void AddResponseToComponents(IOpenApiResponse response, string referenceId = null) + private void AddResponseToComponents(IOpenApiResponse? response, string? referenceId = null) { EnsureComponentsExist(); EnsureResponsesExist(); - if (!Components.Responses.ContainsKey(referenceId)) + if (Components.Responses is not null && referenceId is not null && response is not null && !Components.Responses.ContainsKey(referenceId)) { Components.Responses.Add(referenceId, response); } } - private void AddRequestBodyToComponents(IOpenApiRequestBody requestBody, string referenceId = null) + private void AddRequestBodyToComponents(IOpenApiRequestBody? requestBody, string? referenceId = null) { EnsureComponentsExist(); EnsureRequestBodiesExist(); - if (!Components.RequestBodies.ContainsKey(referenceId)) + if (Components.RequestBodies is not null && requestBody is not null && referenceId is not null && !Components.RequestBodies.ContainsKey(referenceId)) { Components.RequestBodies.Add(referenceId, requestBody); } } - private void AddLinkToComponents(IOpenApiLink link, string referenceId = null) + private void AddLinkToComponents(IOpenApiLink? link, string? referenceId = null) { EnsureComponentsExist(); EnsureLinksExist(); - if (!Components.Links.ContainsKey(referenceId)) + if (Components.Links is not null && link is not null && referenceId is not null && !Components.Links.ContainsKey(referenceId)) { Components.Links.Add(referenceId, link); } } - private void AddCallbackToComponents(IOpenApiCallback callback, string referenceId = null) + private void AddCallbackToComponents(IOpenApiCallback? callback, string? referenceId = null) { EnsureComponentsExist(); EnsureCallbacksExist(); - if (!Components.Callbacks.ContainsKey(referenceId)) + if (Components.Callbacks is not null && callback is not null && referenceId is not null && !Components.Callbacks.ContainsKey(referenceId)) { Components.Callbacks.Add(referenceId, callback); } } - private void AddHeaderToComponents(IOpenApiHeader header, string referenceId = null) + private void AddHeaderToComponents(IOpenApiHeader? header, string? referenceId = null) { EnsureComponentsExist(); EnsureHeadersExist(); - if (!Components.Headers.ContainsKey(referenceId)) + if (Components.Headers is not null && header is not null && referenceId is not null && !Components.Headers.ContainsKey(referenceId)) { Components.Headers.Add(referenceId, header); } } - private void AddExampleToComponents(IOpenApiExample example, string referenceId = null) + private void AddExampleToComponents(IOpenApiExample? example, string? referenceId = null) { EnsureComponentsExist(); EnsureExamplesExist(); - if (!Components.Examples.ContainsKey(referenceId)) + if (Components.Examples is not null && example is not null && referenceId is not null && !Components.Examples.ContainsKey(referenceId)) { Components.Examples.Add(referenceId, example); } } - private void AddPathItemToComponents(IOpenApiPathItem pathItem, string referenceId = null) + private void AddPathItemToComponents(IOpenApiPathItem? pathItem, string? referenceId = null) { EnsureComponentsExist(); EnsurePathItemsExist(); - if (!Components.PathItems.ContainsKey(referenceId)) + if (Components.PathItems is not null && pathItem is not null && referenceId is not null && !Components.PathItems.ContainsKey(referenceId)) { Components.PathItems.Add(referenceId, pathItem); } } - private void AddSecuritySchemeToComponents(IOpenApiSecurityScheme securityScheme, string referenceId = null) + private void AddSecuritySchemeToComponents(IOpenApiSecurityScheme? securityScheme, string? referenceId = null) { EnsureComponentsExist(); EnsureSecuritySchemesExist(); - if (!Components.SecuritySchemes.ContainsKey(referenceId)) + if (Components.SecuritySchemes is not null && securityScheme is not null && referenceId is not null && !Components.SecuritySchemes.ContainsKey(referenceId)) { Components.SecuritySchemes.Add(referenceId, securityScheme); } @@ -184,7 +184,7 @@ public override void Visit(IOpenApiSchema schema) // This is needed to handle schemas used in Responses in components if (schema is OpenApiSchemaReference openApiSchemaReference) { - AddSchemaToComponents(openApiSchemaReference.Target, openApiSchemaReference.Reference.Id); + AddSchemaToComponents(openApiSchemaReference.Target, openApiSchemaReference.Reference?.Id); } base.Visit(schema); } @@ -196,50 +196,80 @@ private void EnsureComponentsExist() private void EnsureSchemasExist() { - _target.Components.Schemas ??= new Dictionary(); + if (_target.Components is not null) + { + _target.Components.Schemas ??= new Dictionary(); + } } private void EnsureParametersExist() { - _target.Components.Parameters ??= new Dictionary(); + if (_target.Components is not null) + { + _target.Components.Parameters ??= new Dictionary(); + } } private void EnsureResponsesExist() { - _target.Components.Responses ??= new Dictionary(); + if (_target.Components is not null) + { + _target.Components.Responses ??= new Dictionary(); + } } private void EnsureRequestBodiesExist() { - _target.Components.RequestBodies ??= new Dictionary(); + if (_target.Components is not null) + { + _target.Components.RequestBodies ??= new Dictionary(); + } } private void EnsureExamplesExist() { - _target.Components.Examples ??= new Dictionary(); + if (_target.Components is not null) + { + _target.Components.Examples ??= new Dictionary(); + } } private void EnsureHeadersExist() { - _target.Components.Headers ??= new Dictionary(); + if (_target.Components is not null) + { + _target.Components.Headers ??= new Dictionary(); + } } private void EnsureCallbacksExist() { - _target.Components.Callbacks ??= new Dictionary(); + if (_target.Components is not null) + { + _target.Components.Callbacks ??= new Dictionary(); + } } private void EnsureLinksExist() { - _target.Components.Links ??= new Dictionary(); + if (_target.Components is not null) + { + _target.Components.Links ??= new Dictionary(); + } } private void EnsureSecuritySchemesExist() { - _target.Components.SecuritySchemes ??= new Dictionary(); + if (_target.Components is not null) + { + _target.Components.SecuritySchemes ??= new Dictionary(); + } } private void EnsurePathItemsExist() { - _target.Components.PathItems ??= new Dictionary(); + if (_target.Components is not null) + { + _target.Components.PathItems = new Dictionary(); + } } } diff --git a/src/Microsoft.OpenApi/Services/LoopDetector.cs b/src/Microsoft.OpenApi/Services/LoopDetector.cs index 904361f97..dd9c0919f 100644 --- a/src/Microsoft.OpenApi/Services/LoopDetector.cs +++ b/src/Microsoft.OpenApi/Services/LoopDetector.cs @@ -20,7 +20,7 @@ public bool PushLoop(T key) _loopStacks.Add(typeof(T), stack); } - if (!stack.Contains(key)) + if (key is not null && !stack.Contains(key)) { stack.Push(key); return true; @@ -48,7 +48,10 @@ public void SaveLoop(T loop) { Loops[typeof(T)] = new(); } - Loops[typeof(T)].Add(loop); + if (loop is not null) + { + Loops[typeof(T)].Add(loop); + } } /// diff --git a/src/Microsoft.OpenApi/Services/OpenApiFilterService.cs b/src/Microsoft.OpenApi/Services/OpenApiFilterService.cs index b17195c3b..82a09c249 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiFilterService.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiFilterService.cs @@ -27,10 +27,10 @@ public static class OpenApiFilterService /// The input OpenAPI document. /// A predicate. public static Func CreatePredicate( - string operationIds = null, - string tags = null, - Dictionary> requestUrls = null, - OpenApiDocument source = null) + string? operationIds = null, + string? tags = null, + Dictionary>? requestUrls = null, + OpenApiDocument? source = null) { Func predicate; ValidateFilters(requestUrls, operationIds, tags); @@ -42,7 +42,7 @@ public static Func CreatePredicate( { predicate = GetTagsPredicate(tags); } - else if (requestUrls != null) + else if (requestUrls != null && source is not null) { predicate = GetRequestUrlsPredicate(requestUrls, source); } @@ -88,36 +88,39 @@ public static OpenApiDocument CreateFilteredDocument(OpenApiDocument source, Fun var results = FindOperations(source, predicate); foreach (var result in results) { - IOpenApiPathItem pathItem; - var pathKey = result.CurrentKeys.Path; + IOpenApiPathItem? pathItem = null; + var pathKey = result.CurrentKeys?.Path; if (subset.Paths == null) { subset.Paths = new(); pathItem = new OpenApiPathItem(); - subset.Paths.Add(pathKey, pathItem); + if (pathKey is not null) + { + subset.Paths.Add(pathKey, pathItem); + } } else { - if (!subset.Paths.TryGetValue(pathKey, out pathItem)) + if (pathKey is not null && !subset.Paths.TryGetValue(pathKey, out pathItem)) { pathItem = new OpenApiPathItem(); subset.Paths.Add(pathKey, pathItem); } } - if (result.CurrentKeys.Operation != null) + if (result.CurrentKeys?.Operation != null && result.Operation != null) { - pathItem.Operations.Add(result.CurrentKeys.Operation, result.Operation); + pathItem?.Operations?.Add(result.CurrentKeys.Operation, result.Operation); if (result.Parameters?.Any() ?? false) { foreach (var parameter in result.Parameters) { - if (!pathItem.Parameters.Contains(parameter)) + if (pathItem?.Parameters is not null && !pathItem.Parameters.Contains(parameter)) { pathItem.Parameters.Add(parameter); - } + } } } } @@ -148,7 +151,7 @@ public static OpenApiUrlTreeNode CreateOpenApiUrlTreeNode(Dictionary GetOpenApiOperations(OpenApiUrlTreeNode rootNode, string relativeUrl, string label) + private static IDictionary? GetOpenApiOperations(OpenApiUrlTreeNode rootNode, string relativeUrl, string label) { if (relativeUrl.Equals("/", StringComparison.Ordinal) && rootNode.HasOperations(label)) { @@ -157,7 +160,7 @@ private static IDictionary GetOpenApiOperations(Op var urlSegments = relativeUrl.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - IDictionary operations = null; + IDictionary? operations = null; var targetChild = rootNode; @@ -247,93 +250,120 @@ private static void CopyReferences(OpenApiDocument target) } while (morestuff); } - private static bool AddReferences(OpenApiComponents newComponents, OpenApiComponents target) + private static bool AddReferences(OpenApiComponents newComponents, OpenApiComponents? target) { var moreStuff = false; - foreach (var item in newComponents.Schemas) + if (newComponents.Schemas is not null) { - if (!target.Schemas.ContainsKey(item.Key)) + foreach (var item in newComponents.Schemas) { - moreStuff = true; - target.Schemas.Add(item); + if (target?.Schemas is not null && !target.Schemas.ContainsKey(item.Key)) + { + moreStuff = true; + target.Schemas.Add(item); + } } } - foreach (var item in newComponents.Parameters) + if (newComponents.Parameters is not null) { - if (!target.Parameters.ContainsKey(item.Key)) + foreach (var item in newComponents.Parameters) { - moreStuff = true; - target.Parameters.Add(item); + if (target?.Parameters is not null && !target.Parameters.ContainsKey(item.Key)) + { + moreStuff = true; + target.Parameters.Add(item); + } } } - foreach (var item in newComponents.Responses) + if (newComponents.Responses is not null) { - if (!target.Responses.ContainsKey(item.Key)) + foreach (var item in newComponents.Responses) { - moreStuff = true; - target.Responses.Add(item); + if (target?.Responses is not null && !target.Responses.ContainsKey(item.Key)) + { + moreStuff = true; + target.Responses.Add(item); + } } } - foreach (var item in newComponents.RequestBodies - .Where(item => !target.RequestBodies.ContainsKey(item.Key))) + if (newComponents.RequestBodies is not null) { - moreStuff = true; - target.RequestBodies.Add(item); + foreach (var item in newComponents.RequestBodies + .Where(item => target?.RequestBodies is not null && !target.RequestBodies.ContainsKey(item.Key))) + { + moreStuff = true; + target?.RequestBodies?.Add(item); + } } - foreach (var item in newComponents.Headers - .Where(item => !target.Headers.ContainsKey(item.Key))) + if (newComponents.Headers is not null) { - moreStuff = true; - target.Headers.Add(item); + foreach (var item in newComponents.Headers + .Where(item => target?.Headers is not null && !target.Headers.ContainsKey(item.Key))) + { + moreStuff = true; + target?.Headers?.Add(item); + } } - foreach (var item in newComponents.Links - .Where(item => !target.Links.ContainsKey(item.Key))) + if (newComponents.Links is not null) { - moreStuff = true; - target.Links.Add(item); + foreach (var item in newComponents.Links + .Where(item => target?.Links is not null && !target.Links.ContainsKey(item.Key))) + { + moreStuff = true; + target?.Links?.Add(item); + } } - foreach (var item in newComponents.Callbacks - .Where(item => !target.Callbacks.ContainsKey(item.Key))) + if (newComponents.Callbacks is not null) { - moreStuff = true; - target.Callbacks.Add(item); + foreach (var item in newComponents.Callbacks + .Where(item => target?.Callbacks is not null && !target.Callbacks.ContainsKey(item.Key))) + { + moreStuff = true; + target?.Callbacks?.Add(item); + } } - foreach (var item in newComponents.Examples - .Where(item => !target.Examples.ContainsKey(item.Key))) + if (newComponents.Examples is not null) { - moreStuff = true; - target.Examples.Add(item); + foreach (var item in newComponents.Examples + .Where(item => target?.Examples is not null && !target.Examples.ContainsKey(item.Key))) + { + moreStuff = true; + target?.Examples?.Add(item); + } } - foreach (var item in newComponents.SecuritySchemes - .Where(item => !target.SecuritySchemes.ContainsKey(item.Key))) + if (newComponents.SecuritySchemes is not null) { - moreStuff = true; - target.SecuritySchemes.Add(item); + foreach (var item in newComponents.SecuritySchemes + .Where(item => target?.SecuritySchemes is not null && !target.SecuritySchemes.ContainsKey(item.Key))) + { + moreStuff = true; + target?.SecuritySchemes?.Add(item); + } } return moreStuff; } - private static string ExtractPath(string url, IList serverList) + private static string ExtractPath(string url, IList? serverList) { // if OpenAPI has servers, then see if the url matches one of them - var baseUrl = serverList.Select(s => s.Url.TrimEnd('/')) - .FirstOrDefault(c => url.Contains(c)); + var baseUrl = serverList?.Select(s => s.Url?.TrimEnd('/')) + .FirstOrDefault(c => c != null && url.Contains(c)); return baseUrl == null ? new Uri(new(SRResource.DefaultBaseUri), url).GetComponents(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.Unescaped) : url.Split(new[] { baseUrl }, StringSplitOptions.None)[1]; } - private static void ValidateFilters(IDictionary> requestUrls, string operationIds, string tags) + private static void ValidateFilters(IDictionary>? requestUrls, string? operationIds, string? tags) { if (requestUrls != null && (operationIds != null || tags != null)) { @@ -364,7 +394,7 @@ private static Func GetTagsPredicate if (tagsArray.Length == 1) { var regex = new Regex(tagsArray[0]); - return (_, _, operation) => operation.Tags?.Any(tag => regex.IsMatch(tag.Name)) ?? false; + return (_, _, operation) => operation.Tags?.Any(tag => tag.Name is not null && regex.IsMatch(tag.Name)) ?? false; } else { @@ -378,22 +408,25 @@ private static Func GetRequestUrlsPr if (source != null) { var apiVersion = source.Info.Version; - var sources = new Dictionary { { apiVersion, source } }; - var rootNode = CreateOpenApiUrlTreeNode(sources); - - // Iterate through urls dictionary and fetch operations for each url - foreach (var url in requestUrls) + if (apiVersion is not null) { - var serverList = source.Servers; - var path = ExtractPath(url.Key, serverList); - var openApiOperations = GetOpenApiOperations(rootNode, path, apiVersion); - if (openApiOperations == null) + var sources = new Dictionary { { apiVersion, source } }; + var rootNode = CreateOpenApiUrlTreeNode(sources); + + // Iterate through urls dictionary and fetch operations for each url + foreach (var url in requestUrls) { - Debug.WriteLine($"The url {url.Key} could not be found in the OpenApi description"); - continue; + var serverList = source.Servers; + var path = ExtractPath(url.Key, serverList); + var openApiOperations = GetOpenApiOperations(rootNode, path, apiVersion); + if (openApiOperations == null) + { + Debug.WriteLine($"The url {url.Key} could not be found in the OpenApi description"); + continue; + } + operationTypes.AddRange(GetOperationTypes(openApiOperations, url.Value, path)); } - operationTypes.AddRange(GetOperationTypes(openApiOperations, url.Value, path)); - } + } } if (!operationTypes.Any()) diff --git a/src/Microsoft.OpenApi/Services/OpenApiReferenceError.cs b/src/Microsoft.OpenApi/Services/OpenApiReferenceError.cs index 6dfd066ff..c9e3eda78 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiReferenceError.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiReferenceError.cs @@ -14,7 +14,7 @@ public class OpenApiReferenceError : OpenApiError /// /// The reference that caused the error. /// - public readonly OpenApiReference Reference; + public readonly OpenApiReference? Reference; /// /// Initializes the class using the message and pointer from the given exception. /// diff --git a/src/Microsoft.OpenApi/Services/OpenApiUrlTreeNode.cs b/src/Microsoft.OpenApi/Services/OpenApiUrlTreeNode.cs index 8a61772dd..ab1a33e0b 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiUrlTreeNode.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiUrlTreeNode.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; @@ -93,7 +93,7 @@ public static OpenApiUrlTreeNode Create(OpenApiDocument doc, string label) var root = Create(); - var paths = doc.Paths; + var paths = doc?.Paths; if (paths != null) { foreach (var path in paths) @@ -283,7 +283,9 @@ private static void ProcessNode(OpenApiUrlTreeNode node, TextWriter writer) private static string GetMethods(OpenApiUrlTreeNode node) { - return String.Join("_", node.PathItems.SelectMany(p => p.Value.Operations.Select(o => o.Key)) + return String.Join("_", node.PathItems + .Where(p => p.Value.Operations != null) + .SelectMany(p => p.Value.Operations!.Select(o => o.Key)) .Distinct() .Select(o => o.ToString().ToUpper()) .OrderBy(o => o) diff --git a/src/Microsoft.OpenApi/Services/OpenApiWalker.cs b/src/Microsoft.OpenApi/Services/OpenApiWalker.cs index b9b053c96..cf07356d3 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiWalker.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiWalker.cs @@ -36,7 +36,7 @@ public OpenApiWalker(OpenApiVisitorBase visitor) /// Visits list of and child objects /// /// OpenApiDocument to be walked - public void Walk(OpenApiDocument doc) + public void Walk(OpenApiDocument? doc) { if (doc == null) { @@ -62,7 +62,7 @@ public void Walk(OpenApiDocument doc) /// /// Visits list of and child objects /// - internal void Walk(ISet tags) + internal void Walk(ISet? tags) { if (tags == null) { @@ -85,7 +85,7 @@ internal void Walk(ISet tags) /// /// Visits list of and child objects /// - internal void Walk(ISet tags) + internal void Walk(ISet? tags) { if (tags == null) { @@ -121,7 +121,7 @@ internal void Walk(string externalDocs) /// /// Visits and child objects /// - internal void Walk(OpenApiExternalDocs externalDocs) + internal void Walk(OpenApiExternalDocs? externalDocs) { if (externalDocs == null) { @@ -285,7 +285,7 @@ internal void Walk(OpenApiPaths paths) /// /// Visits Webhooks and child objects /// - internal void Walk(IDictionary webhooks) + internal void Walk(IDictionary? webhooks) { if (webhooks == null) { @@ -303,13 +303,13 @@ internal void Walk(IDictionary webhooks) Walk(pathItem.Key, () => Walk(pathItem.Value));// JSON Pointer uses ~1 as an escape character for / _visitor.CurrentKeys.Path = null; } - }; + } } /// /// Visits list of and child objects /// - internal void Walk(IList servers) + internal void Walk(IList? servers) { if (servers == null) { @@ -350,7 +350,7 @@ internal void Walk(OpenApiInfo info) /// /// Visits dictionary of extensions /// - internal void Walk(IOpenApiExtensible openApiExtensible) + internal void Walk(IOpenApiExtensible? openApiExtensible) { if (openApiExtensible == null) { @@ -386,7 +386,7 @@ internal void Walk(IOpenApiExtension extension) /// /// Visits and child objects /// - internal void Walk(OpenApiLicense license) + internal void Walk(OpenApiLicense? license) { if (license == null) { @@ -399,7 +399,7 @@ internal void Walk(OpenApiLicense license) /// /// Visits and child objects /// - internal void Walk(OpenApiContact contact) + internal void Walk(OpenApiContact? contact) { if (contact == null) { @@ -427,7 +427,7 @@ internal void Walk(IOpenApiCallback callback, bool isComponent = false) _visitor.Visit(callback); - if (callback != null) + if (callback.PathItems != null) { foreach (var item in callback.PathItems) { @@ -450,7 +450,10 @@ internal void Walk(OpenApiTag tag) } _visitor.Visit(tag); - _visitor.Visit(tag.ExternalDocs); + if (tag.ExternalDocs != null) + { + _visitor.Visit(tag.ExternalDocs); + } _visitor.Visit(tag as IOpenApiExtensible); } @@ -473,7 +476,7 @@ internal void Walk(OpenApiTagReference tag) /// /// Visits and child objects /// - internal void Walk(OpenApiServer server) + internal void Walk(OpenApiServer? server) { if (server == null) { @@ -488,7 +491,7 @@ internal void Walk(OpenApiServer server) /// /// Visits dictionary of /// - internal void Walk(IDictionary serverVariables) + internal void Walk(IDictionary? serverVariables) { if (serverVariables == null) { @@ -554,15 +557,18 @@ internal void Walk(IOpenApiPathItem pathItem, bool isComponent = false) Walk(OpenApiConstants.Parameters, () => Walk(pathItem.Parameters)); Walk(pathItem.Operations); } - _visitor.Visit(pathItem as IOpenApiExtensible); + if (pathItem is IOpenApiExtensible extensiblePathItem) + { + _visitor.Visit(extensiblePathItem); + } _pathItemLoop.Pop(); } /// /// Visits dictionary of /// - internal void Walk(IDictionary operations) + internal void Walk(IDictionary? operations) { if (operations == null) { @@ -606,7 +612,7 @@ internal void Walk(OpenApiOperation operation) /// /// Visits list of /// - internal void Walk(IList securityRequirements) + internal void Walk(IList? securityRequirements) { if (securityRequirements == null) { @@ -627,7 +633,7 @@ internal void Walk(IList securityRequirements) /// /// Visits list of /// - internal void Walk(IList parameters) + internal void Walk(IList? parameters) { if (parameters == null) { @@ -672,7 +678,7 @@ internal void Walk(IOpenApiParameter parameter, bool isComponent = false) /// /// Visits and child objects /// - internal void Walk(OpenApiResponses responses) + internal void Walk(OpenApiResponses? responses) { if (responses == null) { @@ -719,7 +725,7 @@ internal void Walk(IOpenApiResponse response, bool isComponent = false) /// /// Visits and child objects /// - internal void Walk(IOpenApiRequestBody requestBody, bool isComponent = false) + internal void Walk(IOpenApiRequestBody? requestBody, bool isComponent = false) { if (requestBody == null) { @@ -744,7 +750,7 @@ internal void Walk(IOpenApiRequestBody requestBody, bool isComponent = false) /// /// Visits dictionary of /// - internal void Walk(IDictionary headers) + internal void Walk(IDictionary? headers) { if (headers == null) { @@ -766,7 +772,7 @@ internal void Walk(IDictionary headers) /// /// Visits dictionary of /// - internal void Walk(IDictionary callbacks) + internal void Walk(IDictionary? callbacks) { if (callbacks == null) { @@ -788,7 +794,7 @@ internal void Walk(IDictionary callbacks) /// /// Visits dictionary of /// - internal void Walk(IDictionary content) + internal void Walk(IDictionary? content) { if (content == null) { @@ -828,7 +834,7 @@ internal void Walk(OpenApiMediaType mediaType) /// /// Visits dictionary of /// - internal void Walk(IDictionary encodings) + internal void Walk(IDictionary? encodings) { if (encodings == null) { @@ -870,7 +876,7 @@ internal void Walk(OpenApiEncoding encoding) /// /// Visits and child objects /// - internal void Walk(IOpenApiSchema schema, bool isComponent = false) + internal void Walk(IOpenApiSchema? schema, bool isComponent = false) { if (schema == null || schema is IOpenApiReferenceHolder holder && ProcessAsReference(holder, isComponent)) { @@ -940,7 +946,7 @@ internal void Walk(IOpenApiSchema schema, bool isComponent = false) /// /// Visits dictionary of /// - internal void Walk(IDictionary examples) + internal void Walk(IDictionary? examples) { if (examples == null) { @@ -963,7 +969,7 @@ internal void Walk(IDictionary examples) /// /// Visits and child objects /// - internal void Walk(JsonNode example) + internal void Walk(JsonNode? example) { if (example == null) { @@ -1065,7 +1071,7 @@ internal void Walk(OpenApiOAuthFlow oAuthFlow) /// /// Visits dictionary of and child objects /// - internal void Walk(IDictionary links) + internal void Walk(IDictionary? links) { if (links == null) { @@ -1258,56 +1264,56 @@ public class CurrentKeys /// /// Current Path key /// - public string Path { get; set; } + public string? Path { get; set; } /// /// Current Operation Type /// - public HttpMethod Operation { get; set; } + public HttpMethod? Operation { get; set; } /// /// Current Response Status Code /// - public string Response { get; set; } + public string? Response { get; set; } /// /// Current Content Media Type /// - public string Content { get; set; } + public string? Content { get; set; } /// /// Current Callback Key /// - public string Callback { get; set; } + public string? Callback { get; set; } /// /// Current Link Key /// - public string Link { get; set; } + public string? Link { get; set; } /// /// Current Header Key /// - public string Header { get; internal set; } + public string? Header { get; internal set; } /// /// Current Encoding Key /// - public string Encoding { get; internal set; } + public string? Encoding { get; internal set; } /// /// Current Example Key /// - public string Example { get; internal set; } + public string? Example { get; internal set; } /// /// Current Extension Key /// - public string Extension { get; internal set; } + public string? Extension { get; internal set; } /// /// Current ServerVariable /// - public string ServerVariable { get; internal set; } + public string? ServerVariable { get; internal set; } } } diff --git a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs index ec368a6c0..d668626db 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs @@ -23,7 +23,7 @@ public class OpenApiWorkspace /// /// The base location from where all relative references are resolved /// - public Uri BaseUrl { get; } + public Uri? BaseUrl { get; } /// /// Initialize workspace pointing to a base URL to allow resolving relative document locations. Use a file:// url to point to a folder @@ -69,78 +69,107 @@ public void RegisterComponents(OpenApiDocument document) string location; // Register Schema - foreach (var item in document.Components.Schemas) + if (document.Components.Schemas != null) { - location = item.Value.Id ?? baseUri + ReferenceType.Schema.GetDisplayName() + ComponentSegmentSeparator + item.Key; - - RegisterComponent(location, item.Value); + foreach (var item in document.Components.Schemas) + { + location = item.Value.Id ?? baseUri + ReferenceType.Schema.GetDisplayName() + ComponentSegmentSeparator + item.Key; + RegisterComponent(location, item.Value); + } } // Register Parameters - foreach (var item in document.Components.Parameters) + if (document.Components.Parameters != null) { - location = baseUri + ReferenceType.Parameter.GetDisplayName() + ComponentSegmentSeparator + item.Key; - RegisterComponent(location, item.Value); + foreach (var item in document.Components.Parameters) + { + location = baseUri + ReferenceType.Parameter.GetDisplayName() + ComponentSegmentSeparator + item.Key; + RegisterComponent(location, item.Value); + } } // Register Responses - foreach (var item in document.Components.Responses) + if (document.Components.Responses != null) { - location = baseUri + ReferenceType.Response.GetDisplayName() + ComponentSegmentSeparator + item.Key; - RegisterComponent(location, item.Value); + foreach (var item in document.Components.Responses) + { + location = baseUri + ReferenceType.Response.GetDisplayName() + ComponentSegmentSeparator + item.Key; + RegisterComponent(location, item.Value); + } } // Register RequestBodies - foreach (var item in document.Components.RequestBodies) + if (document.Components.RequestBodies != null) { - location = baseUri + ReferenceType.RequestBody.GetDisplayName() + ComponentSegmentSeparator + item.Key; - RegisterComponent(location, item.Value); + foreach (var item in document.Components.RequestBodies) + { + location = baseUri + ReferenceType.RequestBody.GetDisplayName() + ComponentSegmentSeparator + item.Key; + RegisterComponent(location, item.Value); + } } // Register Links - foreach (var item in document.Components.Links) + if (document.Components.Links != null) { - location = baseUri + ReferenceType.Link.GetDisplayName() + ComponentSegmentSeparator + item.Key; - RegisterComponent(location, item.Value); + foreach (var item in document.Components.Links) + { + location = baseUri + ReferenceType.Link.GetDisplayName() + ComponentSegmentSeparator + item.Key; + RegisterComponent(location, item.Value); + } } // Register Callbacks - foreach (var item in document.Components.Callbacks) + if (document.Components.Callbacks != null) { - location = baseUri + ReferenceType.Callback.GetDisplayName() + ComponentSegmentSeparator + item.Key; - RegisterComponent(location, item.Value); + foreach (var item in document.Components.Callbacks) + { + location = baseUri + ReferenceType.Callback.GetDisplayName() + ComponentSegmentSeparator + item.Key; + RegisterComponent(location, item.Value); + } } // Register PathItems - foreach (var item in document.Components.PathItems) + if (document.Components.PathItems != null) { - location = baseUri + ReferenceType.PathItem.GetDisplayName() + ComponentSegmentSeparator + item.Key; - RegisterComponent(location, item.Value); + foreach (var item in document.Components.PathItems) + { + location = baseUri + ReferenceType.PathItem.GetDisplayName() + ComponentSegmentSeparator + item.Key; + RegisterComponent(location, item.Value); + } } // Register Examples - foreach (var item in document.Components.Examples) + if (document.Components.Examples != null) { - location = baseUri + ReferenceType.Example.GetDisplayName() + ComponentSegmentSeparator + item.Key; - RegisterComponent(location, item.Value); + foreach (var item in document.Components.Examples) + { + location = baseUri + ReferenceType.Example.GetDisplayName() + ComponentSegmentSeparator + item.Key; + RegisterComponent(location, item.Value); + } } // Register Headers - foreach (var item in document.Components.Headers) + if (document.Components.Headers != null) { - location = baseUri + ReferenceType.Header.GetDisplayName() + ComponentSegmentSeparator + item.Key; - RegisterComponent(location, item.Value); + foreach (var item in document.Components.Headers) + { + location = baseUri + ReferenceType.Header.GetDisplayName() + ComponentSegmentSeparator + item.Key; + RegisterComponent(location, item.Value); + } } // Register SecuritySchemes - foreach (var item in document.Components.SecuritySchemes) + if (document.Components.SecuritySchemes != null) { - location = baseUri + ReferenceType.SecurityScheme.GetDisplayName() + ComponentSegmentSeparator + item.Key; - RegisterComponent(location, item.Value); + foreach (var item in document.Components.SecuritySchemes) + { + location = baseUri + ReferenceType.SecurityScheme.GetDisplayName() + ComponentSegmentSeparator + item.Key; + RegisterComponent(location, item.Value); + } } } - private string getBaseUri(OpenApiDocument openApiDocument) + private static string getBaseUri(OpenApiDocument openApiDocument) { return openApiDocument.BaseUri + OpenApiConstants.ComponentsSegment; } @@ -176,7 +205,7 @@ public bool RegisterComponentForDocument(OpenApiDocument openApiDocument, T c IOpenApiExample => baseUri + ReferenceType.Example.GetDisplayName() + ComponentSegmentSeparator + id, IOpenApiHeader => baseUri + ReferenceType.Header.GetDisplayName() + ComponentSegmentSeparator + id, IOpenApiSecurityScheme => baseUri + ReferenceType.SecurityScheme.GetDisplayName() + ComponentSegmentSeparator + id, - _ => throw new ArgumentException($"Invalid component type {componentToRegister.GetType().Name}"), + _ => throw new ArgumentException($"Invalid component type {componentToRegister!.GetType().Name}"), }; return RegisterComponent(location, componentToRegister); @@ -191,22 +220,23 @@ public bool RegisterComponentForDocument(OpenApiDocument openApiDocument, T c internal bool RegisterComponent(string location, T component) { var uri = ToLocationUrl(location); - if (component is IOpenApiReferenceable referenceable) + if (uri is not null) { - if (!_IOpenApiReferenceableRegistry.ContainsKey(uri)) + if (component is IOpenApiReferenceable referenceable) { - _IOpenApiReferenceableRegistry[uri] = referenceable; - return true; + if (!_IOpenApiReferenceableRegistry.ContainsKey(uri)) + { + _IOpenApiReferenceableRegistry[uri] = referenceable; + return true; + } } - } - else if (component is Stream stream) - { - if (!_artifactsRegistry.ContainsKey(uri)) + else if (component is Stream stream && !_artifactsRegistry.ContainsKey(uri)) { _artifactsRegistry[uri] = stream; return true; } - } + return false; + } return false; } @@ -216,9 +246,9 @@ internal bool RegisterComponent(string location, T component) /// /// /// - public void AddDocumentId(string key, Uri value) + public void AddDocumentId(string? key, Uri? value) { - if (!_documentsIdRegistry.ContainsKey(key)) + if (!string.IsNullOrEmpty(key) && key is not null && value is not null && !_documentsIdRegistry.ContainsKey(key)) { _documentsIdRegistry[key] = value; } @@ -229,12 +259,13 @@ public void AddDocumentId(string key, Uri value) /// /// /// The document id of the given key. - public Uri GetDocumentId(string key) + public Uri? GetDocumentId(string? key) { - if (_documentsIdRegistry.TryGetValue(key, out var id)) + if (key is not null && _documentsIdRegistry.TryGetValue(key, out var id)) { return id; } + return null; } @@ -246,6 +277,7 @@ public Uri GetDocumentId(string key) public bool Contains(string location) { var key = ToLocationUrl(location); + if (key is null) return false; return _IOpenApiReferenceableRegistry.ContainsKey(key) || _artifactsRegistry.ContainsKey(key); } @@ -260,23 +292,30 @@ public bool Contains(string location) { if (string.IsNullOrEmpty(location)) return default; - var uri = ToLocationUrl(location); - if (_IOpenApiReferenceableRegistry.TryGetValue(uri, out var referenceableValue)) - { - return (T)referenceableValue; - } - else if (_artifactsRegistry.TryGetValue(uri, out var artifact)) + var uri = ToLocationUrl(location); + if (uri is not null) { - return (T)(object)artifact; - } + if (_IOpenApiReferenceableRegistry.TryGetValue(uri, out var referenceableValue) && referenceableValue is T referenceable) + { + return referenceable; + } + else if (_artifactsRegistry.TryGetValue(uri, out var artifact) && artifact is T artifactValue) + { + return artifactValue; + } + } return default; } #nullable restore - private Uri ToLocationUrl(string location) + private Uri? ToLocationUrl(string location) { - return new(BaseUrl, location); + if (BaseUrl is not null) + { + return new(BaseUrl, location); + } + return null; } } } diff --git a/src/Microsoft.OpenApi/Services/OperationSearch.cs b/src/Microsoft.OpenApi/Services/OperationSearch.cs index d3199f38c..ff2de5d2d 100644 --- a/src/Microsoft.OpenApi/Services/OperationSearch.cs +++ b/src/Microsoft.OpenApi/Services/OperationSearch.cs @@ -35,21 +35,24 @@ public OperationSearch(Func predicat /// public override void Visit(IOpenApiPathItem pathItem) { - foreach (var item in pathItem.Operations) + if (pathItem.Operations is not null) { - var operation = item.Value; - var operationType = item.Key; - - if (_predicate(CurrentKeys.Path, operationType, operation)) + foreach (var item in pathItem.Operations) { - _searchResults.Add(new() + var operation = item.Value; + var operationType = item.Key; + + if (CurrentKeys.Path is not null && _predicate(CurrentKeys.Path, operationType, operation)) { - Operation = operation, - Parameters = pathItem.Parameters, - CurrentKeys = CopyCurrentKeys(CurrentKeys, operationType) - }); + _searchResults.Add(new() + { + Operation = operation, + Parameters = pathItem.Parameters, + CurrentKeys = CopyCurrentKeys(CurrentKeys, operationType) + }); + } } - } + } } /// diff --git a/src/Microsoft.OpenApi/Services/SearchResult.cs b/src/Microsoft.OpenApi/Services/SearchResult.cs index 6bbeed27a..2fea9e03d 100644 --- a/src/Microsoft.OpenApi/Services/SearchResult.cs +++ b/src/Microsoft.OpenApi/Services/SearchResult.cs @@ -15,16 +15,16 @@ public class SearchResult /// /// An object containing contextual information based on where the walker is currently referencing in an OpenApiDocument. /// - public CurrentKeys CurrentKeys { get; set; } + public CurrentKeys? CurrentKeys { get; set; } /// /// An Operation object. /// - public OpenApiOperation Operation { get; set; } + public OpenApiOperation? Operation { get; set; } /// /// Parameters object /// - public IList Parameters { get; set; } + public IList? Parameters { get; set; } } } diff --git a/src/Microsoft.OpenApi/Validations/IValidationContext.cs b/src/Microsoft.OpenApi/Validations/IValidationContext.cs index 36c26baa6..c7c257c56 100644 --- a/src/Microsoft.OpenApi/Validations/IValidationContext.cs +++ b/src/Microsoft.OpenApi/Validations/IValidationContext.cs @@ -37,10 +37,5 @@ public interface IValidationContext /// Pointer to source of validation error in document /// string PathString { get; } - - /// - /// - /// - OpenApiDocument HostDocument { get; } } } diff --git a/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs b/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs index 734c514c3..54bd92deb 100644 --- a/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs +++ b/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs @@ -25,11 +25,9 @@ public class OpenApiValidator : OpenApiVisitorBase, IValidationContext /// Create a visitor that will validate an OpenAPIDocument /// /// - /// - public OpenApiValidator(ValidationRuleSet ruleSet, OpenApiDocument hostDocument = null) + public OpenApiValidator(ValidationRuleSet ruleSet) { _ruleSet = ruleSet; - HostDocument = hostDocument; } /// @@ -42,11 +40,6 @@ public OpenApiValidator(ValidationRuleSet ruleSet, OpenApiDocument hostDocument /// public IEnumerable Warnings { get => _warnings; } - /// - /// The host document used for validation. - /// - public OpenApiDocument HostDocument { get; set; } - /// /// Register an error with the validation context. /// @@ -183,7 +176,7 @@ private void Validate(T item) /// This overload allows applying rules based on actual object type, rather than matched interface. This is /// needed for validating extensions. /// - private void Validate(object item, Type type) + private void Validate(object? item, Type type) { if (item == null) { @@ -197,10 +190,13 @@ private void Validate(object item, Type type) } var rules = _ruleSet.FindRules(type); - foreach (var rule in rules) + if (rules is not null) { - rule.Evaluate(this, item); - } + foreach (var rule in rules) + { + rule.Evaluate(this, item); + } + } } } } diff --git a/src/Microsoft.OpenApi/Validations/Rules/OpenApiComponentsRules.cs b/src/Microsoft.OpenApi/Validations/Rules/OpenApiComponentsRules.cs index bd14f93ed..80ab4e9ab 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/OpenApiComponentsRules.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/OpenApiComponentsRules.cs @@ -46,7 +46,7 @@ public static class OpenApiComponentsRules ValidateKeys(context, components.Callbacks?.Keys, "callbacks"); }); - private static void ValidateKeys(IValidationContext context, IEnumerable keys, string component) + private static void ValidateKeys(IValidationContext context, IEnumerable? keys, string component) { if (keys == null) { diff --git a/src/Microsoft.OpenApi/Validations/Rules/OpenApiExtensionRules.cs b/src/Microsoft.OpenApi/Validations/Rules/OpenApiExtensionRules.cs index 545f68f85..9853acb37 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/OpenApiExtensionRules.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/OpenApiExtensionRules.cs @@ -23,12 +23,15 @@ public static class OpenApiExtensibleRules (context, item) => { context.Enter("extensions"); - foreach (var extensible in item.Extensions.Keys.Where(static x => !x.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase))) + if (item.Extensions is not null) { - context.CreateError(nameof(ExtensionNameMustStartWithXDash), - string.Format(SRResource.Validation_ExtensionNameMustBeginWithXDash, extensible, context.PathString)); - } - context.Exit(); + foreach (var extensible in item.Extensions.Keys.Where(static x => !x.StartsWith(OpenApiConstants.ExtensionFieldNamePrefix, StringComparison.OrdinalIgnoreCase))) + { + context.CreateError(nameof(ExtensionNameMustStartWithXDash), + string.Format(SRResource.Validation_ExtensionNameMustBeginWithXDash, extensible, context.PathString)); + } + context.Exit(); + } }); } } diff --git a/src/Microsoft.OpenApi/Validations/Rules/OpenApiNonDefaultRules.cs b/src/Microsoft.OpenApi/Validations/Rules/OpenApiNonDefaultRules.cs index 03661401c..70dc7396a 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/OpenApiNonDefaultRules.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/OpenApiNonDefaultRules.cs @@ -89,9 +89,9 @@ public static class OpenApiNonDefaultRules private static void ValidateMismatchedDataType(IValidationContext context, string ruleName, - JsonNode example, - IDictionary examples, - IOpenApiSchema schema) + JsonNode? example, + IDictionary? examples, + IOpenApiSchema? schema) { // example context.Enter("example"); diff --git a/src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs b/src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs index b954c96b6..9884d54dd 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/OpenApiSchemaRules.cs @@ -46,28 +46,32 @@ public static class OpenApiSchemaRules /// The parent schema. /// Adds support for polymorphism. The discriminator is an object name that is used to differentiate /// between other schemas which may satisfy the payload description. - public static bool ValidateChildSchemaAgainstDiscriminator(IOpenApiSchema schema, string discriminatorName) + public static bool ValidateChildSchemaAgainstDiscriminator(IOpenApiSchema schema, string? discriminatorName) { - if (!schema.Required?.Contains(discriminatorName) ?? false) + if (discriminatorName is not null) { - // recursively check nested schema.OneOf, schema.AnyOf or schema.AllOf and their required fields for the discriminator - if (schema.OneOf.Count != 0) + if (!schema.Required?.Contains(discriminatorName) ?? false) { - return TraverseSchemaElements(discriminatorName, schema.OneOf); - } - if (schema.AnyOf.Count != 0) - { - return TraverseSchemaElements(discriminatorName, schema.AnyOf); + // recursively check nested schema.OneOf, schema.AnyOf or schema.AllOf and their required fields for the discriminator + if (schema.OneOf?.Count != 0) + { + return TraverseSchemaElements(discriminatorName, schema.OneOf); + } + if (schema.AnyOf?.Count != 0) + { + return TraverseSchemaElements(discriminatorName, schema.AnyOf); + } + if (schema.AllOf?.Count != 0) + { + return TraverseSchemaElements(discriminatorName, schema.AllOf); + } } - if (schema.AllOf.Count != 0) + else { - return TraverseSchemaElements(discriminatorName, schema.AllOf); + return true; } - } - else - { - return true; - } + return false; + } return false; } @@ -79,20 +83,24 @@ public static bool ValidateChildSchemaAgainstDiscriminator(IOpenApiSchema schema /// between other schemas which may satisfy the payload description. /// The child schema. /// - public static bool TraverseSchemaElements(string discriminatorName, IList childSchema) + public static bool TraverseSchemaElements(string discriminatorName, IList? childSchema) { - foreach (var childItem in childSchema) + if (childSchema is not null) { - if ((!childItem.Properties?.ContainsKey(discriminatorName) ?? false) && - (!childItem.Required?.Contains(discriminatorName) ?? false)) + foreach (var childItem in childSchema) { - return ValidateChildSchemaAgainstDiscriminator(childItem, discriminatorName); - } - else - { - return true; + if ((!childItem.Properties?.ContainsKey(discriminatorName) ?? false) && + (!childItem.Required?.Contains(discriminatorName) ?? false)) + { + return ValidateChildSchemaAgainstDiscriminator(childItem, discriminatorName); + } + else + { + return true; + } } - } + return false; + } return false; } diff --git a/src/Microsoft.OpenApi/Validations/Rules/OpenApiServerRules.cs b/src/Microsoft.OpenApi/Validations/Rules/OpenApiServerRules.cs index 35d4b9a25..d4ffc5429 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/OpenApiServerRules.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/OpenApiServerRules.cs @@ -29,13 +29,16 @@ public static class OpenApiServerRules context.Exit(); context.Enter("variables"); - foreach (var variable in server.Variables) + if (server.Variables is not null) { - context.Enter(variable.Key); - ValidateServerVariableRequiredFields(context, variable.Key, variable.Value); + foreach (var variable in server.Variables) + { + context.Enter(variable.Key); + ValidateServerVariableRequiredFields(context, variable.Key, variable.Value); + context.Exit(); + } context.Exit(); - } - context.Exit(); + } }); // add more rules diff --git a/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs b/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs index 71f46255f..1b4896d3a 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs @@ -45,8 +45,8 @@ public static bool IsEmailAddress(this string input) public static void ValidateDataTypeMismatch( IValidationContext context, string ruleName, - JsonNode value, - IOpenApiSchema schema) + JsonNode? value, + IOpenApiSchema? schema) { if (schema == null) { @@ -54,14 +54,14 @@ public static void ValidateDataTypeMismatch( } // convert value to JsonElement and access the ValueKind property to determine the type. - var valueKind = value.GetValueKind(); + var valueKind = value?.GetValueKind(); var type = (schema.Type & ~JsonSchemaType.Null)?.ToFirstIdentifier(); var format = schema.Format; // Before checking the type, check first if the schema allows null. // If so and the data given is also null, this is allowed for any type. - if ((schema.Type.Value & JsonSchemaType.Null) is JsonSchemaType.Null && valueKind is JsonValueKind.Null) + if (schema.Type is not null && (schema.Type.Value & JsonSchemaType.Null) is JsonSchemaType.Null && valueKind is JsonValueKind.Null) { return; } diff --git a/src/Microsoft.OpenApi/Validations/ValidationRuleSet.cs b/src/Microsoft.OpenApi/Validations/ValidationRuleSet.cs index 3e38d65b2..d09d9b566 100644 --- a/src/Microsoft.OpenApi/Validations/ValidationRuleSet.cs +++ b/src/Microsoft.OpenApi/Validations/ValidationRuleSet.cs @@ -18,9 +18,9 @@ public sealed class ValidationRuleSet { private Dictionary> _rulesDictionary = new(); - private static ValidationRuleSet _defaultRuleSet; + private static ValidationRuleSet? _defaultRuleSet; - private List _emptyRules = new(); + private readonly List _emptyRules = new(); /// @@ -62,10 +62,7 @@ public IList FindRules(Type type) public static ValidationRuleSet GetDefaultRuleSet() { // Reflection can be an expensive operation, so we cache the default rule set that has already been built. - if (_defaultRuleSet == null) - { - _defaultRuleSet = BuildDefaultRuleSet(); - } + _defaultRuleSet ??= BuildDefaultRuleSet(); // We create a new instance of ValidationRuleSet per call as a safeguard // against unintentional modification of the private _defaultRuleSet. @@ -219,7 +216,7 @@ public void Remove(string ruleName) /// true if the rule is successfully removed; otherwise, false. public bool Remove(Type key, ValidationRule rule) { - if (_rulesDictionary.TryGetValue(key, out IList validationRules)) + if (_rulesDictionary.TryGetValue(key, out IList? validationRules)) { return validationRules.Remove(rule); } @@ -263,7 +260,7 @@ public bool ContainsKey(Type key) /// public bool Contains(Type key, ValidationRule rule) { - return _rulesDictionary.TryGetValue(key, out IList validationRules) && validationRules.Contains(rule); + return _rulesDictionary.TryGetValue(key, out IList? validationRules) && validationRules.Contains(rule); } /// @@ -274,7 +271,7 @@ public bool Contains(Type key, ValidationRule rule) /// key is found; otherwise, an empty object. /// This parameter is passed uninitialized. /// true if the specified key has rules. - public bool TryGetValue(Type key, out IList rules) + public bool TryGetValue(Type key, out IList? rules) { return _rulesDictionary.TryGetValue(key, out rules); } diff --git a/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs b/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs index 15b7b07f7..93b4c5e14 100644 --- a/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.cs +++ b/src/Microsoft.OpenApi/Writers/OpenApiJsonWriter.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; @@ -34,7 +34,7 @@ public OpenApiJsonWriter(TextWriter textWriter, OpenApiJsonWriterSettings settin /// The text writer. /// Settings for controlling how the OpenAPI document will be written out. /// Setting for allowing the JSON emitted to be in terse format. - public OpenApiJsonWriter(TextWriter textWriter, OpenApiWriterSettings settings, bool terseOutput = false) : base(textWriter, settings) + public OpenApiJsonWriter(TextWriter textWriter, OpenApiWriterSettings? settings, bool terseOutput = false) : base(textWriter, settings) { _produceTerseOutput = terseOutput; } @@ -59,7 +59,7 @@ public override void WriteStartObject() var currentScope = StartScope(ScopeType.Object); - if (previousScope is {Type: ScopeType.Array}) + if (previousScope is { Type: ScopeType.Array }) { currentScope.IsInArray = true; @@ -110,7 +110,7 @@ public override void WriteStartArray() var currentScope = StartScope(ScopeType.Array); - if (previousScope is {Type: ScopeType.Array}) + if (previousScope is { Type: ScopeType.Array }) { currentScope.IsInArray = true; @@ -158,14 +158,14 @@ public override void WritePropertyName(string name) VerifyCanWritePropertyName(name); var currentScope = CurrentScope(); - if (currentScope.ObjectCount != 0) + if (currentScope?.ObjectCount != 0) { Writer.Write(WriterConstants.ObjectMemberSeparator); } WriteLine(); - currentScope.ObjectCount++; + currentScope!.ObjectCount++; WriteIndentation(); diff --git a/src/Microsoft.OpenApi/Writers/OpenApiWriterAnyExtensions.cs b/src/Microsoft.OpenApi/Writers/OpenApiWriterAnyExtensions.cs index f7559f0f7..eee8068a9 100644 --- a/src/Microsoft.OpenApi/Writers/OpenApiWriterAnyExtensions.cs +++ b/src/Microsoft.OpenApi/Writers/OpenApiWriterAnyExtensions.cs @@ -22,7 +22,7 @@ public static class OpenApiWriterAnyExtensions /// The Open API writer. /// The specification extensions. /// Version of the OpenAPI specification that that will be output. - public static void WriteExtensions(this IOpenApiWriter writer, IDictionary extensions, OpenApiSpecVersion specVersion) + public static void WriteExtensions(this IOpenApiWriter writer, IDictionary? extensions, OpenApiSpecVersion specVersion) { Utils.CheckArgumentNull(writer); @@ -49,7 +49,7 @@ public static void WriteExtensions(this IOpenApiWriter writer, IDictionary /// The Open API writer. /// The JsonNode value - public static void WriteAny(this IOpenApiWriter writer, JsonNode node) + public static void WriteAny(this IOpenApiWriter writer, JsonNode? node) { Utils.CheckArgumentNull(writer); @@ -84,34 +84,37 @@ public static void WriteAny(this IOpenApiWriter writer, JsonNode node) } } - private static void WriteArray(this IOpenApiWriter writer, JsonArray array) + private static void WriteArray(this IOpenApiWriter writer, JsonArray? array) { writer.WriteStartArray(); - - foreach (var item in array) + if (array is not null) { - writer.WriteAny(item); - } + foreach (var item in array) + { + writer.WriteAny(item); + } + } writer.WriteEndArray(); } - private static void WriteObject(this IOpenApiWriter writer, JsonObject entity) + private static void WriteObject(this IOpenApiWriter writer, JsonObject? entity) { writer.WriteStartObject(); - - foreach (var item in entity) + if (entity is not null) { - writer.WritePropertyName(item.Key); - writer.WriteAny(item.Value); + foreach (var item in entity) + { + writer.WritePropertyName(item.Key); + writer.WriteAny(item.Value); + } } - writer.WriteEndObject(); } private static void WritePrimitive(this IOpenApiWriter writer, JsonValue jsonValue) { - if (jsonValue.TryGetValue(out string stringValue)) + if (jsonValue.TryGetValue(out string? stringValue)) writer.WriteValue(stringValue); else if (jsonValue.TryGetValue(out DateTime dateTimeValue)) writer.WriteValue(dateTimeValue.ToString("o", CultureInfo.InvariantCulture)); // ISO 8601 format diff --git a/src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs b/src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs index aa515af7e..0f212477a 100644 --- a/src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs +++ b/src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.OpenApi.Exceptions; @@ -52,7 +53,7 @@ protected OpenApiWriterBase(TextWriter textWriter) : this(textWriter, null) /// /// /// - protected OpenApiWriterBase(TextWriter textWriter, OpenApiWriterSettings settings) + protected OpenApiWriterBase(TextWriter textWriter, OpenApiWriterSettings? settings) { Writer = textWriter; Writer.NewLine = "\n"; @@ -229,7 +230,7 @@ public virtual void WriteEnumerable(IEnumerable collection) /// Write object value. /// /// The object value. - public virtual void WriteValue(object value) + public virtual void WriteValue(object? value) { if (value == null) { @@ -332,7 +333,7 @@ public virtual void WriteIndentation() /// Get current scope. /// /// - protected Scope CurrentScope() + protected Scope? CurrentScope() { return Scopes.Count == 0 ? null : Scopes.Peek(); } @@ -437,7 +438,7 @@ protected void VerifyCanWritePropertyName(string name) } /// - public void WriteV2Examples(IOpenApiWriter writer, OpenApiExample example, OpenApiSpecVersion version) + public static void WriteV2Examples(IOpenApiWriter writer, OpenApiExample example, OpenApiSpecVersion version) { writer.WriteStartObject(); diff --git a/src/Microsoft.OpenApi/Writers/OpenApiWriterExtensions.cs b/src/Microsoft.OpenApi/Writers/OpenApiWriterExtensions.cs index 0e0256f79..ad84d5537 100644 --- a/src/Microsoft.OpenApi/Writers/OpenApiWriterExtensions.cs +++ b/src/Microsoft.OpenApi/Writers/OpenApiWriterExtensions.cs @@ -21,7 +21,7 @@ public static class OpenApiWriterExtensions /// The writer. /// The property name. /// The property value. - public static void WriteProperty(this IOpenApiWriter writer, string name, string value) + public static void WriteProperty(this IOpenApiWriter writer, string name, string? value) { if (value == null) { @@ -39,7 +39,7 @@ public static void WriteProperty(this IOpenApiWriter writer, string name, string /// The writer. /// The property name. /// The property value. - public static void WriteRequiredProperty(this IOpenApiWriter writer, string name, string value) + public static void WriteRequiredProperty(this IOpenApiWriter writer, string name, string? value) { Utils.CheckArgumentNullOrEmpty(name); writer.WritePropertyName(name); @@ -191,8 +191,8 @@ public static void WriteRequiredObject( public static void WriteOptionalCollection( this IOpenApiWriter writer, string name, - IEnumerable elements, - Action action) + IEnumerable? elements, + Action action) { if (elements != null && elements.Any()) { @@ -211,7 +211,7 @@ public static void WriteOptionalCollection( public static void WriteOptionalCollection( this IOpenApiWriter writer, string name, - IEnumerable elements, + IEnumerable? elements, Action action) { if (elements != null && elements.Any()) @@ -248,7 +248,7 @@ public static void WriteRequiredCollection( public static void WriteRequiredMap( this IOpenApiWriter writer, string name, - IDictionary elements, + IDictionary? elements, Action action) { writer.WriteMapInternal(name, elements, action); @@ -264,7 +264,7 @@ public static void WriteRequiredMap( public static void WriteOptionalMap( this IOpenApiWriter writer, string name, - IDictionary elements, + IDictionary? elements, Action action) { if (elements != null && elements.Any()) @@ -283,7 +283,7 @@ public static void WriteOptionalMap( public static void WriteOptionalMap( this IOpenApiWriter writer, string name, - IDictionary elements, + IDictionary? elements, Action action) { if (elements != null && elements.Any()) @@ -302,7 +302,7 @@ public static void WriteOptionalMap( public static void WriteOptionalMap( this IOpenApiWriter writer, string name, - IDictionary elements, + IDictionary? elements, Action action) { if (elements != null && elements.Any()) @@ -321,7 +321,7 @@ public static void WriteOptionalMap( public static void WriteOptionalMap( this IOpenApiWriter writer, string name, - IDictionary> elements, + IDictionary>? elements, Action> action) { if (elements != null && elements.Any()) @@ -341,7 +341,7 @@ public static void WriteOptionalMap( public static void WriteOptionalMap( this IOpenApiWriter writer, string name, - IDictionary elements, + IDictionary? elements, Action action) where T : IOpenApiElement { @@ -362,7 +362,7 @@ public static void WriteOptionalMap( public static void WriteOptionalMap( this IOpenApiWriter writer, string name, - IDictionary elements, + IDictionary? elements, Action action) where T : IOpenApiElement { @@ -383,7 +383,7 @@ public static void WriteOptionalMap( public static void WriteRequiredMap( this IOpenApiWriter writer, string name, - IDictionary elements, + IDictionary? elements, Action action) where T : IOpenApiElement { @@ -421,7 +421,7 @@ private static void WriteCollectionInternal( private static void WriteMapInternal( this IOpenApiWriter writer, string name, - IDictionary elements, + IDictionary? elements, Action action) { WriteMapInternal(writer, name, elements, (w, _, s) => action(w, s)); @@ -430,7 +430,7 @@ private static void WriteMapInternal( private static void WriteMapInternal( this IOpenApiWriter writer, string name, - IDictionary elements, + IDictionary? elements, Action action) { Utils.CheckArgumentNull(action); diff --git a/src/Microsoft.OpenApi/Writers/OpenApiYamlWriter.cs b/src/Microsoft.OpenApi/Writers/OpenApiYamlWriter.cs index aaa160548..49e8f0cb4 100644 --- a/src/Microsoft.OpenApi/Writers/OpenApiYamlWriter.cs +++ b/src/Microsoft.OpenApi/Writers/OpenApiYamlWriter.cs @@ -24,7 +24,7 @@ public OpenApiYamlWriter(TextWriter textWriter) : this(textWriter, null) /// /// The text writer. /// - public OpenApiYamlWriter(TextWriter textWriter, OpenApiWriterSettings settings) : base(textWriter, settings) + public OpenApiYamlWriter(TextWriter textWriter, OpenApiWriterSettings? settings) : base(textWriter, settings) { } @@ -49,7 +49,7 @@ public override void WriteStartObject() var currentScope = StartScope(ScopeType.Object); - if (previousScope is {Type: ScopeType.Array}) + if (previousScope is { Type: ScopeType.Array }) { currentScope.IsInArray = true; @@ -77,7 +77,7 @@ public override void WriteEndObject() if (previousScope.ObjectCount == 0) { // If we are in an object, write a white space preceding the braces. - if (currentScope is {Type: ScopeType.Object}) + if (currentScope is { Type: ScopeType.Object }) { Writer.Write(" "); } @@ -95,7 +95,7 @@ public override void WriteStartArray() var currentScope = StartScope(ScopeType.Array); - if (previousScope is {Type: ScopeType.Array}) + if (previousScope is { Type: ScopeType.Array }) { currentScope.IsInArray = true; @@ -123,7 +123,7 @@ public override void WriteEndArray() if (previousScope.ObjectCount == 0) { // If we are in an object, write a white space preceding the braces. - if (currentScope is {Type: ScopeType.Object}) + if (currentScope is { Type: ScopeType.Object }) { Writer.Write(" "); } @@ -142,7 +142,7 @@ public override void WritePropertyName(string name) var currentScope = CurrentScope(); // If this is NOT the first property in the object, always start a new line and add indentation. - if (currentScope.ObjectCount != 0) + if (currentScope?.ObjectCount != 0) { Writer.WriteLine(); WriteIndentation(); @@ -161,7 +161,7 @@ public override void WritePropertyName(string name) Writer.Write(name); Writer.Write(":"); - currentScope.ObjectCount++; + currentScope!.ObjectCount++; } /// @@ -170,7 +170,7 @@ public override void WritePropertyName(string name) /// The string value. public override void WriteValue(string value) { - if (!UseLiteralStyle || value.IndexOfAny(new[] { '\n', '\r' }) == -1) + if (!UseLiteralStyle || value?.IndexOfAny(new[] { '\n', '\r' }) == -1) { WriteValueSeparator(); @@ -190,7 +190,7 @@ public override void WriteValue(string value) WriteChompingIndicator(value); // Write indentation indicator when it starts with spaces - if (value.StartsWith(" ", StringComparison.OrdinalIgnoreCase)) + if (value is not null && value.StartsWith(" ", StringComparison.OrdinalIgnoreCase)) { Writer.Write(IndentationString.Length); } @@ -199,7 +199,7 @@ public override void WriteValue(string value) IncreaseIndentation(); - using (var reader = new StringReader(value)) + using (var reader = new StringReader(value!)) { var firstLine = true; while (reader.ReadLine() is var line && line != null) @@ -223,10 +223,10 @@ public override void WriteValue(string value) } } - private void WriteChompingIndicator(string value) + private void WriteChompingIndicator(string? value) { var trailingNewlines = 0; - var end = value.Length - 1; + var end = value!.Length - 1; // We only need to know whether there are 0, 1, or more trailing newlines while (end >= 0 && trailingNewlines < 2) { @@ -288,8 +288,9 @@ protected override void WriteValueSeparator() { if (IsArrayScope()) { + var objectCount = CurrentScope()!.ObjectCount; // If array is the outermost scope and this is the first item, there is no need to insert a newline. - if (!IsTopLevelScope() || CurrentScope().ObjectCount != 0) + if (!IsTopLevelScope() || objectCount != 0) { Writer.WriteLine(); } @@ -297,7 +298,7 @@ protected override void WriteValueSeparator() WriteIndentation(); Writer.Write(WriterConstants.PrefixOfArrayItem); - CurrentScope().ObjectCount++; + CurrentScope()!.ObjectCount++; } else { diff --git a/test/Microsoft.OpenApi.Hidi.Tests/Formatters/PowerShellFormatterTests.cs b/test/Microsoft.OpenApi.Hidi.Tests/Formatters/PowerShellFormatterTests.cs index 49b020a10..92cfae013 100644 --- a/test/Microsoft.OpenApi.Hidi.Tests/Formatters/PowerShellFormatterTests.cs +++ b/test/Microsoft.OpenApi.Hidi.Tests/Formatters/PowerShellFormatterTests.cs @@ -51,7 +51,7 @@ public void FormatOperationIdsInOpenAPIDocument(string operationId, string expec walker.Walk(openApiDocument); // Assert - Assert.Equal(expectedOperationId, openApiDocument.Paths[path].Operations[operationType].OperationId); + Assert.Equal(expectedOperationId, openApiDocument.Paths[path].Operations?[operationType].OperationId); } [Fact] @@ -68,20 +68,20 @@ public void RemoveAnyOfAndOneOfFromSchema() Assert.NotNull(openApiDocument.Components); Assert.NotNull(openApiDocument.Components.Schemas); var testSchema = openApiDocument.Components.Schemas["TestSchema"]; - var averageAudioDegradationProperty = testSchema.Properties["averageAudioDegradation"]; - var defaultPriceProperty = testSchema.Properties["defaultPrice"]; + var averageAudioDegradationProperty = testSchema.Properties?["averageAudioDegradation"]; + var defaultPriceProperty = testSchema.Properties?["defaultPrice"]; // Assert Assert.NotNull(openApiDocument.Components); Assert.NotNull(openApiDocument.Components.Schemas); Assert.NotNull(testSchema); - Assert.Null(averageAudioDegradationProperty.AnyOf); - Assert.Equal(JsonSchemaType.Number | JsonSchemaType.Null, averageAudioDegradationProperty.Type); - Assert.Equal("float", averageAudioDegradationProperty.Format); - Assert.Equal(JsonSchemaType.Null, averageAudioDegradationProperty.Type & JsonSchemaType.Null); - Assert.Null(defaultPriceProperty.OneOf); - Assert.Equal(JsonSchemaType.Number, defaultPriceProperty.Type); - Assert.Equal("double", defaultPriceProperty.Format); + Assert.Null(averageAudioDegradationProperty?.AnyOf); + Assert.Equal(JsonSchemaType.Number | JsonSchemaType.Null, averageAudioDegradationProperty?.Type); + Assert.Equal("float", averageAudioDegradationProperty?.Format); + Assert.Equal(JsonSchemaType.Null, averageAudioDegradationProperty?.Type & JsonSchemaType.Null); + Assert.Null(defaultPriceProperty?.OneOf); + Assert.Equal(JsonSchemaType.Number, defaultPriceProperty?.Type); + Assert.Equal("double", defaultPriceProperty?.Format); Assert.NotNull(testSchema.AdditionalProperties); } @@ -96,7 +96,7 @@ public void ResolveFunctionParameters() var walker = new OpenApiWalker(powerShellFormatter); walker.Walk(openApiDocument); - var idsParameter = openApiDocument.Paths["/foo"].Operations[HttpMethod.Get].Parameters?.Where(static p => p.Name == "ids").FirstOrDefault(); + var idsParameter = openApiDocument.Paths["/foo"].Operations?[HttpMethod.Get].Parameters?.Where(static p => p.Name == "ids").FirstOrDefault(); // Assert Assert.Null(idsParameter?.Content); diff --git a/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiFilterServiceTests.cs b/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiFilterServiceTests.cs index 57d2d5098..7702c56c1 100644 --- a/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiFilterServiceTests.cs +++ b/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiFilterServiceTests.cs @@ -104,9 +104,9 @@ public void TestPredicateFiltersUsingRelativeRequestUrls() var predicate = OpenApiFilterService.CreatePredicate(requestUrls: requestUrls, source: openApiDocument); // Then - Assert.True(predicate("/foo", HttpMethod.Get, null)); - Assert.True(predicate("/foo", HttpMethod.Post, null)); - Assert.False(predicate("/foo", HttpMethod.Patch, null)); + Assert.True(predicate("/foo", HttpMethod.Get, null!)); + Assert.True(predicate("/foo", HttpMethod.Post, null!)); + Assert.False(predicate("/foo", HttpMethod.Patch, null!)); } [Fact] @@ -157,7 +157,7 @@ public void CreateFilteredDocumentUsingPredicateFromRequestUrl() // Assert that there's only 1 parameter in the subset document Assert.NotNull(subsetDoc); Assert.NotEmpty(subsetDoc.Paths); - Assert.Single(subsetDoc.Paths.First().Value.Parameters); + Assert.Single(subsetDoc.Paths.First().Value.Parameters!); } [Fact] @@ -239,52 +239,55 @@ public async Task CopiesOverAllReferencedComponentsToTheSubsetDocumentCorrectly( var settings = new OpenApiReaderSettings(); settings.AddYamlReader(); var doc = (await OpenApiDocument.LoadAsync(stream, "yaml", settings)).Document; - + // validated the tags are read as references - var openApiOperationTags = doc.Paths["/items"].Operations[HttpMethod.Get].Tags?.ToArray(); + var openApiOperationTags = doc?.Paths["/items"].Operations?[HttpMethod.Get].Tags?.ToArray(); Assert.NotNull(openApiOperationTags); Assert.Single(openApiOperationTags); Assert.True(openApiOperationTags[0].UnresolvedReference); - - var predicate = OpenApiFilterService.CreatePredicate(operationIds: operationIds); - var subsetOpenApiDocument = OpenApiFilterService.CreateFilteredDocument(doc, predicate); - - var response = subsetOpenApiDocument.Paths["/items"].Operations[HttpMethod.Get]?.Responses?["200"]; - var responseHeader = response?.Headers["x-custom-header"]; - var mediaTypeExample = response?.Content["application/json"]?.Examples?.First().Value; - var targetHeaders = subsetOpenApiDocument.Components?.Headers; - var targetExamples = subsetOpenApiDocument.Components?.Examples; - // Assert - Assert.Same(doc.Servers, subsetOpenApiDocument.Servers); - var headerReference = Assert.IsType(responseHeader); - Assert.False(headerReference.UnresolvedReference); - var exampleReference = Assert.IsType(mediaTypeExample); - Assert.False(exampleReference?.UnresolvedReference); - Assert.NotNull(targetHeaders); - Assert.Single(targetHeaders); - Assert.NotNull(targetExamples); - Assert.Single(targetExamples); - // validated the tags of the trimmed document are read as references - var trimmedOpenApiOperationTags = subsetOpenApiDocument.Paths["/items"].Operations[HttpMethod.Get].Tags?.ToArray(); - Assert.NotNull(trimmedOpenApiOperationTags); - Assert.Single(trimmedOpenApiOperationTags); - Assert.True(trimmedOpenApiOperationTags[0].UnresolvedReference); - - // Finally try to write the trimmed document as v3 document - var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter) + var predicate = OpenApiFilterService.CreatePredicate(operationIds: operationIds); + if (doc is not null) { - Settings = new OpenApiWriterSettings() + var subsetOpenApiDocument = OpenApiFilterService.CreateFilteredDocument(doc, predicate); + + var response = subsetOpenApiDocument.Paths?["/items"].Operations?[HttpMethod.Get]?.Responses?["200"]; + var responseHeader = response?.Headers?["x-custom-header"]; + var mediaTypeExample = response?.Content?["application/json"]?.Examples?.First().Value; + var targetHeaders = subsetOpenApiDocument.Components?.Headers; + var targetExamples = subsetOpenApiDocument.Components?.Examples; + + // Assert + Assert.Same(doc.Servers, subsetOpenApiDocument.Servers); + var headerReference = Assert.IsType(responseHeader); + Assert.False(headerReference.UnresolvedReference); + var exampleReference = Assert.IsType(mediaTypeExample); + Assert.False(exampleReference?.UnresolvedReference); + Assert.NotNull(targetHeaders); + Assert.Single(targetHeaders); + Assert.NotNull(targetExamples); + Assert.Single(targetExamples); + // validated the tags of the trimmed document are read as references + var trimmedOpenApiOperationTags = subsetOpenApiDocument.Paths?["/items"].Operations?[HttpMethod.Get].Tags?.ToArray(); + Assert.NotNull(trimmedOpenApiOperationTags); + Assert.Single(trimmedOpenApiOperationTags); + Assert.True(trimmedOpenApiOperationTags[0].UnresolvedReference); + + // Finally try to write the trimmed document as v3 document + var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); + var writer = new OpenApiJsonWriter(outputStringWriter) { - InlineExternalReferences = true, - InlineLocalReferences = true - } - }; - subsetOpenApiDocument.SerializeAsV3(writer); - await writer.FlushAsync(); - var result = outputStringWriter.ToString(); - Assert.NotEmpty(result); + Settings = new OpenApiWriterSettings() + { + InlineExternalReferences = true, + InlineLocalReferences = true + } + }; + subsetOpenApiDocument.SerializeAsV3(writer); + await writer.FlushAsync(); + var result = outputStringWriter.ToString(); + Assert.NotEmpty(result); + } } [Theory] @@ -299,8 +302,8 @@ public void ReturnsPathParametersOnSlicingBasedOnOperationIdsOrTags(string? oper // Assert foreach (var pathItem in subsetOpenApiDocument.Paths) { - Assert.True(pathItem.Value.Parameters.Any()); - Assert.Single(pathItem.Value.Parameters); + Assert.True(pathItem.Value.Parameters!.Any()); + Assert.Single(pathItem.Value.Parameters!); } } } diff --git a/test/Microsoft.OpenApi.Hidi.Tests/UtilityFiles/OpenApiDocumentMock.cs b/test/Microsoft.OpenApi.Hidi.Tests/UtilityFiles/OpenApiDocumentMock.cs index 0cc1bc2fb..71768bfbe 100644 --- a/test/Microsoft.OpenApi.Hidi.Tests/UtilityFiles/OpenApiDocumentMock.cs +++ b/test/Microsoft.OpenApi.Hidi.Tests/UtilityFiles/OpenApiDocumentMock.cs @@ -678,23 +678,23 @@ public static OpenApiDocument CreateOpenApiDocument() } } }; - document.Paths[getTeamsActivityByPeriodPath].Operations[HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("reports.Functions", document)}; - document.Paths[getTeamsActivityByDatePath].Operations[HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("reports.Functions", document)}; - document.Paths[usersPath].Operations[HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("users.user", document)}; - document.Paths[usersByIdPath].Operations[HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("users.user", document)}; - document.Paths[usersByIdPath].Operations[HttpMethod.Patch].Tags = new HashSet {new OpenApiTagReference("users.user", document)}; - document.Paths[messagesByIdPath].Operations[HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("users.message", document)}; - document.Paths[administrativeUnitRestorePath].Operations[HttpMethod.Post].Tags = new HashSet {new OpenApiTagReference("administrativeUnits.Actions", document)}; - document.Paths[logoPath].Operations[HttpMethod.Put].Tags = new HashSet {new OpenApiTagReference("applications.application", document)}; - document.Paths[securityProfilesPath].Operations[HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("security.hostSecurityProfile", document)}; - document.Paths[communicationsCallsKeepAlivePath].Operations[HttpMethod.Post].Tags = new HashSet {new OpenApiTagReference("communications.Actions", document)}; - document.Paths[eventsDeltaPath].Operations[HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("groups.Functions", document)}; - document.Paths[refPath].Operations[HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("applications.directoryObject", document)}; - ((OpenApiSchema)document.Paths[usersPath].Operations[HttpMethod.Get].Responses!["200"].Content[applicationJsonMediaType].Schema!.Properties["value"]).Items = new OpenApiSchemaReference("microsoft.graph.user", document); - document.Paths[usersByIdPath].Operations[HttpMethod.Get].Responses!["200"].Content[applicationJsonMediaType].Schema = new OpenApiSchemaReference("microsoft.graph.user", document); - document.Paths[messagesByIdPath].Operations[HttpMethod.Get].Responses!["200"].Content[applicationJsonMediaType].Schema = new OpenApiSchemaReference("microsoft.graph.message", document); - ((OpenApiSchema)document.Paths[securityProfilesPath].Operations[HttpMethod.Get].Responses!["200"].Content[applicationJsonMediaType].Schema!.Properties["value"]).Items = new OpenApiSchemaReference("microsoft.graph.networkInterface", document); - ((OpenApiSchema)document.Paths[eventsDeltaPath].Operations[HttpMethod.Get].Responses!["200"].Content[applicationJsonMediaType].Schema!.Properties["value"]).Items = new OpenApiSchemaReference("microsoft.graph.event", document); + document.Paths[getTeamsActivityByPeriodPath].Operations![HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("reports.Functions", document)}; + document.Paths[getTeamsActivityByDatePath].Operations![HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("reports.Functions", document)}; + document.Paths[usersPath].Operations![HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("users.user", document)}; + document.Paths[usersByIdPath].Operations![HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("users.user", document)}; + document.Paths[usersByIdPath].Operations![HttpMethod.Patch].Tags = new HashSet {new OpenApiTagReference("users.user", document)}; + document.Paths[messagesByIdPath].Operations![HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("users.message", document)}; + document.Paths[administrativeUnitRestorePath].Operations![HttpMethod.Post].Tags = new HashSet {new OpenApiTagReference("administrativeUnits.Actions", document)}; + document.Paths[logoPath].Operations![HttpMethod.Put].Tags = new HashSet {new OpenApiTagReference("applications.application", document)}; + document.Paths[securityProfilesPath].Operations![HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("security.hostSecurityProfile", document)}; + document.Paths[communicationsCallsKeepAlivePath].Operations![HttpMethod.Post].Tags = new HashSet {new OpenApiTagReference("communications.Actions", document)}; + document.Paths[eventsDeltaPath].Operations![HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("groups.Functions", document)}; + document.Paths[refPath].Operations![HttpMethod.Get].Tags = new HashSet {new OpenApiTagReference("applications.directoryObject", document)}; + ((OpenApiSchema)document.Paths[usersPath].Operations![HttpMethod.Get].Responses!["200"].Content![applicationJsonMediaType].Schema!.Properties!["value"]).Items = new OpenApiSchemaReference("microsoft.graph.user", document); + document.Paths[usersByIdPath].Operations![HttpMethod.Get].Responses!["200"].Content![applicationJsonMediaType].Schema = new OpenApiSchemaReference("microsoft.graph.user", document); + document.Paths[messagesByIdPath].Operations![HttpMethod.Get].Responses!["200"].Content![applicationJsonMediaType].Schema = new OpenApiSchemaReference("microsoft.graph.message", document); + ((OpenApiSchema)document.Paths[securityProfilesPath].Operations![HttpMethod.Get].Responses!["200"].Content![applicationJsonMediaType].Schema!.Properties!["value"]).Items = new OpenApiSchemaReference("microsoft.graph.networkInterface", document); + ((OpenApiSchema)document.Paths[eventsDeltaPath].Operations![HttpMethod.Get].Responses!["200"].Content![applicationJsonMediaType].Schema!.Properties!["value"]).Items = new OpenApiSchemaReference("microsoft.graph.event", document); return document; } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/ParseNodeTests.cs b/test/Microsoft.OpenApi.Readers.Tests/ParseNodeTests.cs index 8dfb20322..082c5e5df 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/ParseNodeTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/ParseNodeTests.cs @@ -28,7 +28,7 @@ public void BrokenSimpleList() var result = OpenApiDocument.Parse(input, "yaml", SettingsFixture.ReaderSettings); Assert.Equivalent(new List() { - new OpenApiError(new OpenApiReaderException("Expected a value.")) + new OpenApiError(new OpenApiReaderException("Expected a value while parsing at #/schemes.")) }, result.Diagnostic.Errors); } diff --git a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV2Tests.cs b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV2Tests.cs deleted file mode 100644 index 59c8a81f8..000000000 --- a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV2Tests.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -using Microsoft.OpenApi.Models; -using Microsoft.OpenApi.Reader; -using Microsoft.OpenApi.Reader.V2; -using Xunit; - -namespace Microsoft.OpenApi.Readers.Tests -{ - public class ConvertToOpenApiReferenceV2Tests - { - public OpenApiDiagnostic Diagnostic { get; } - - public ConvertToOpenApiReferenceV2Tests() - { - Diagnostic = new(); - } - - [Fact] - public void ParseExternalReferenceToV2OpenApi() - { - // Arrange - var versionService = new OpenApiV2VersionService(Diagnostic); - var externalResource = "externalSchema.json"; - var id = "mySchema"; - var input = $"{externalResource}#/definitions/{id}"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, null); - - // Assert - Assert.Equal(externalResource, reference.ExternalResource); - Assert.NotNull(reference.Type); - Assert.Equal(id, reference.Id); - } - - [Fact] - public void ParseExternalReference() - { - // Arrange - var versionService = new OpenApiV2VersionService(Diagnostic); - var externalResource = "externalSchema.json"; - var id = "/externalPathSegment1/externalPathSegment2/externalPathSegment3"; - var input = $"{externalResource}#{id}"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, null); - - // Assert - Assert.Equal(externalResource, reference.ExternalResource); - Assert.Null(reference.Type); - Assert.Equal(id, reference.Id); - } - - [Fact] - public void ParseLocalParameterReference() - { - // Arrange - var versionService = new OpenApiV2VersionService(Diagnostic); - var referenceType = ReferenceType.Parameter; - var id = "parameterId"; - var input = $"#/parameters/{id}"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, referenceType); - - // Assert - Assert.Equal(referenceType, reference.Type); - Assert.Null(reference.ExternalResource); - Assert.Equal(id, reference.Id); - } - - [Fact] - public void ParseLocalSchemaReference() - { - // Arrange - var versionService = new OpenApiV2VersionService(Diagnostic); - var referenceType = ReferenceType.Schema; - var id = "parameterId"; - var input = $"#/definitions/{id}"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, referenceType); - - // Assert - Assert.Equal(referenceType, reference.Type); - Assert.Null(reference.ExternalResource); - Assert.Equal(id, reference.Id); - } - - [Fact] - public void ParseTagReference() - { - // Arrange - var versionService = new OpenApiV2VersionService(Diagnostic); - var referenceType = ReferenceType.Tag; - var id = "tagId"; - var input = $"{id}"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, referenceType); - - // Assert - Assert.Equal(referenceType, reference.Type); - Assert.Null(reference.ExternalResource); - Assert.Equal(id, reference.Id); - } - - [Fact] - public void ParseSecuritySchemeReference() - { - // Arrange - var versionService = new OpenApiV2VersionService(Diagnostic); - var referenceType = ReferenceType.SecurityScheme; - var id = "securitySchemeId"; - var input = $"{id}"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, referenceType); - - // Assert - Assert.Equal(referenceType, reference.Type); - Assert.Null(reference.ExternalResource); - Assert.Equal(id, reference.Id); - } - } -} diff --git a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV3Tests.cs b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV3Tests.cs deleted file mode 100644 index 0104f5208..000000000 --- a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV3Tests.cs +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -using Microsoft.OpenApi.Models; -using Microsoft.OpenApi.Reader; -using Microsoft.OpenApi.Reader.V3; -using Xunit; - -namespace Microsoft.OpenApi.Readers.Tests -{ - public class ConvertToOpenApiReferenceV3Tests - { - public OpenApiDiagnostic Diagnostic { get; } - - public ConvertToOpenApiReferenceV3Tests() - { - Diagnostic = new(); - } - - [Fact] - public void ParseExternalReference() - { - // Arrange - var versionService = new OpenApiV3VersionService(Diagnostic); - var externalResource = "externalSchema.json"; - var id = "/externalPathSegment1/externalPathSegment2/externalPathSegment3"; - var input = $"{externalResource}#{id}"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, null); - - // Assert - Assert.Null(reference.Type); - Assert.Equal(externalResource, reference.ExternalResource); - Assert.Equal(id, reference.Id); - } - - [Fact] - public void ParseLocalParameterReference() - { - // Arrange - var versionService = new OpenApiV3VersionService(Diagnostic); - var referenceType = ReferenceType.Parameter; - var id = "parameterId"; - var input = $"#/components/parameters/{id}"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, referenceType); - - // Assert - Assert.Equal(referenceType, reference.Type); - Assert.Null(reference.ExternalResource); - Assert.Equal(id, reference.Id); - } - - [Fact] - public void ParseLocalSchemaReference() - { - // Arrange - var versionService = new OpenApiV3VersionService(Diagnostic); - var referenceType = ReferenceType.Schema; - var id = "schemaId"; - var input = $"#/components/schemas/{id}"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, referenceType); - - // Assert - Assert.Equal(referenceType, reference.Type); - Assert.Null(reference.ExternalResource); - Assert.Equal(id, reference.Id); - } - - [Fact] - public void ParseTagReference() - { - // Arrange - var versionService = new OpenApiV3VersionService(Diagnostic); - var referenceType = ReferenceType.Tag; - var id = "tagId"; - var input = $"{id}"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, referenceType); - - // Assert - Assert.Equal(referenceType, reference.Type); - Assert.Null(reference.ExternalResource); - Assert.Equal(id, reference.Id); - } - - [Fact] - public void ParseSecuritySchemeReference() - { - // Arrange - var versionService = new OpenApiV3VersionService(Diagnostic); - var referenceType = ReferenceType.SecurityScheme; - var id = "securitySchemeId"; - var input = $"{id}"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, referenceType); - - // Assert - Assert.Equal(referenceType, reference.Type); - Assert.Null(reference.ExternalResource); - Assert.Equal(id, reference.Id); - } - - [Fact] - public void ParseLocalFileReference() - { - // Arrange - var versionService = new OpenApiV3VersionService(Diagnostic); - var referenceType = ReferenceType.Schema; - var input = $"../schemas/collection.json"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, referenceType); - - // Assert - Assert.Equal(referenceType, reference.Type); - Assert.Equal(input, reference.ExternalResource); - } - - [Fact] - public void ParseExternalPathReference() - { - // Arrange - var versionService = new OpenApiV3VersionService(Diagnostic); - var externalResource = "externalSchema.json"; - var referenceJsonEscaped = "/paths/~1applications~1{AppUUID}~1services~1{ServiceName}"; - var input = $"{externalResource}#{referenceJsonEscaped}"; - var id = "/applications/{AppUUID}/services/{ServiceName}"; - - // Act - var reference = versionService.ConvertToOpenApiReference(input, null); - - // Assert - Assert.Null(reference.Type); - Assert.Equal(externalResource, reference.ExternalResource); - Assert.Equal(id, reference.Id); - } - } -} diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiReferenceTests.cs index b75cb89e4..85686fcfa 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiReferenceTests.cs @@ -38,14 +38,14 @@ public void SettingInternalReferenceForComponentsStyleReferenceShouldSucceed( } [Theory] - [InlineData("Pet.json", "Pet.json", null, null)] - [InlineData("Pet.yaml", "Pet.yaml", null, null)] - [InlineData("abc", "abc", null, null)] + [InlineData("Pet.json", "Pet.json", null, ReferenceType.Schema)] + [InlineData("Pet.yaml", "Pet.yaml", null, ReferenceType.Schema)] + [InlineData("abc", "abc", null, ReferenceType.Schema)] [InlineData("Pet.json#/components/schemas/Pet", "Pet.json", "Pet", ReferenceType.Schema)] [InlineData("Pet.yaml#/components/schemas/Pet", "Pet.yaml", "Pet", ReferenceType.Schema)] [InlineData("abc#/components/schemas/Pet", "abc", "Pet", ReferenceType.Schema)] [InlineData("abc#/components/schemas/HttpsValidationProblem", "abc", "HttpsValidationProblem", ReferenceType.Schema)] - public void SettingExternalReferenceV3ShouldSucceed(string expected, string externalResource, string id, ReferenceType? type) + public void SettingExternalReferenceV3ShouldSucceed(string expected, string externalResource, string id, ReferenceType type) { // Arrange & Act var reference = new OpenApiReference @@ -63,13 +63,13 @@ public void SettingExternalReferenceV3ShouldSucceed(string expected, string exte } [Theory] - [InlineData("Pet.json", "Pet.json", null, null)] - [InlineData("Pet.yaml", "Pet.yaml", null, null)] - [InlineData("abc", "abc", null, null)] + [InlineData("Pet.json", "Pet.json", null, ReferenceType.Schema)] + [InlineData("Pet.yaml", "Pet.yaml", null, ReferenceType.Schema)] + [InlineData("abc", "abc", null, ReferenceType.Schema)] [InlineData("Pet.json#/definitions/Pet", "Pet.json", "Pet", ReferenceType.Schema)] [InlineData("Pet.yaml#/definitions/Pet", "Pet.yaml", "Pet", ReferenceType.Schema)] [InlineData("abc#/definitions/Pet", "abc", "Pet", ReferenceType.Schema)] - public void SettingExternalReferenceV2ShouldSucceed(string expected, string externalResource, string id, ReferenceType? type) + public void SettingExternalReferenceV2ShouldSucceed(string expected, string externalResource, string id, ReferenceType type) { // Arrange & Act var reference = new OpenApiReference diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 2e672dde0..6685b34d8 100644 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -27,8 +27,8 @@ namespace Microsoft.OpenApi.Exceptions { public OpenApiException() { } public OpenApiException(string message) { } - public OpenApiException(string message, System.Exception innerException) { } - public string Pointer { get; set; } + public OpenApiException(string message, System.Exception? innerException) { } + public string? Pointer { get; set; } } [System.Serializable] public class OpenApiReaderException : Microsoft.OpenApi.Exceptions.OpenApiException @@ -37,7 +37,6 @@ namespace Microsoft.OpenApi.Exceptions public OpenApiReaderException(string message) { } public OpenApiReaderException(string message, Microsoft.OpenApi.Reader.ParsingContext context) { } public OpenApiReaderException(string message, System.Exception innerException) { } - public OpenApiReaderException(string message, System.Text.Json.Nodes.JsonNode node) { } } [System.Serializable] public class OpenApiUnsupportedSpecVersionException : System.Exception @@ -50,7 +49,7 @@ namespace Microsoft.OpenApi.Exceptions { public OpenApiWriterException() { } public OpenApiWriterException(string message) { } - public OpenApiWriterException(string message, System.Exception innerException) { } + public OpenApiWriterException(string message, System.Exception? innerException) { } } } namespace Microsoft.OpenApi.Expressions @@ -60,9 +59,9 @@ namespace Microsoft.OpenApi.Expressions public const string Body = "body"; public const string PointerPrefix = "#"; public BodyExpression() { } - public BodyExpression(Microsoft.OpenApi.JsonPointer pointer) { } + public BodyExpression(Microsoft.OpenApi.JsonPointer? pointer) { } public override string Expression { get; } - public string Fragment { get; } + public string? Fragment { get; } } public class CompositeExpression : Microsoft.OpenApi.Expressions.RuntimeExpression { @@ -75,7 +74,7 @@ namespace Microsoft.OpenApi.Expressions public const string Header = "header."; public HeaderExpression(string token) { } public override string Expression { get; } - public string Token { get; } + public string? Token { get; } } public sealed class MethodExpression : Microsoft.OpenApi.Expressions.RuntimeExpression { @@ -88,14 +87,14 @@ namespace Microsoft.OpenApi.Expressions public const string Path = "path."; public PathExpression(string name) { } public override string Expression { get; } - public string Name { get; } + public string? Name { get; } } public sealed class QueryExpression : Microsoft.OpenApi.Expressions.SourceExpression { public const string Query = "query."; public QueryExpression(string name) { } public override string Expression { get; } - public string Name { get; } + public string? Name { get; } } public sealed class RequestExpression : Microsoft.OpenApi.Expressions.RuntimeExpression { @@ -116,16 +115,16 @@ namespace Microsoft.OpenApi.Expressions public const string Prefix = "$"; protected RuntimeExpression() { } public abstract string Expression { get; } - public bool Equals(Microsoft.OpenApi.Expressions.RuntimeExpression obj) { } - public override bool Equals(object obj) { } + public bool Equals(Microsoft.OpenApi.Expressions.RuntimeExpression? obj) { } + public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } public static Microsoft.OpenApi.Expressions.RuntimeExpression Build(string expression) { } } public abstract class SourceExpression : Microsoft.OpenApi.Expressions.RuntimeExpression { - protected SourceExpression(string value) { } - protected string Value { get; } + protected SourceExpression(string? value) { } + protected string? Value { get; } public new static Microsoft.OpenApi.Expressions.SourceExpression Build(string expression) { } } public sealed class StatusCodeExpression : Microsoft.OpenApi.Expressions.RuntimeExpression @@ -146,7 +145,7 @@ namespace Microsoft.OpenApi.Extensions public static class EnumExtensions { [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2075", Justification="Fields are never trimmed for enum types.")] - public static T GetAttributeOfType(this System.Enum enumValue) + public static T? GetAttributeOfType(this System.Enum enumValue) where T : System.Attribute { } public static string GetDisplayName(this System.Enum enumValue) { } } @@ -179,12 +178,12 @@ namespace Microsoft.OpenApi.Extensions where T : Microsoft.OpenApi.Interfaces.IOpenApiSerializable { } public static System.Threading.Tasks.Task SerializeAsync(this T element, System.IO.Stream stream, Microsoft.OpenApi.OpenApiSpecVersion specVersion, Microsoft.OpenApi.OpenApiFormat format, System.Threading.CancellationToken cancellationToken = default) where T : Microsoft.OpenApi.Interfaces.IOpenApiSerializable { } - public static System.Threading.Tasks.Task SerializeAsync(this T element, System.IO.Stream stream, Microsoft.OpenApi.OpenApiSpecVersion specVersion, Microsoft.OpenApi.OpenApiFormat format, Microsoft.OpenApi.Writers.OpenApiWriterSettings settings, System.Threading.CancellationToken cancellationToken = default) + public static System.Threading.Tasks.Task SerializeAsync(this T element, System.IO.Stream stream, Microsoft.OpenApi.OpenApiSpecVersion specVersion, Microsoft.OpenApi.OpenApiFormat format, Microsoft.OpenApi.Writers.OpenApiWriterSettings? settings = null, System.Threading.CancellationToken cancellationToken = default) where T : Microsoft.OpenApi.Interfaces.IOpenApiSerializable { } } public static class OpenApiServerExtensions { - public static string ReplaceServerUrlVariables(this Microsoft.OpenApi.Models.OpenApiServer server, System.Collections.Generic.IDictionary values = null) { } + public static string? ReplaceServerUrlVariables(this Microsoft.OpenApi.Models.OpenApiServer server, System.Collections.Generic.IDictionary? values = null) { } } public static class OpenApiTypeMapper { @@ -201,12 +200,12 @@ namespace Microsoft.OpenApi.Interfaces public interface IDiagnostic { } public interface IMetadataContainer { - System.Collections.Generic.IDictionary Metadata { get; set; } + System.Collections.Generic.IDictionary? Metadata { get; set; } } public interface IOpenApiElement { } public interface IOpenApiExtensible : Microsoft.OpenApi.Interfaces.IOpenApiElement { - System.Collections.Generic.IDictionary Extensions { get; set; } + System.Collections.Generic.IDictionary? Extensions { get; set; } } public interface IOpenApiExtension { @@ -214,13 +213,13 @@ namespace Microsoft.OpenApi.Interfaces } public interface IOpenApiReadOnlyExtensible { - System.Collections.Generic.IDictionary Extensions { get; } + System.Collections.Generic.IDictionary? Extensions { get; } } public interface IOpenApiReader { Microsoft.OpenApi.Reader.ReadResult Read(System.IO.MemoryStream input, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings); System.Threading.Tasks.Task ReadAsync(System.IO.Stream input, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings, System.Threading.CancellationToken cancellationToken = default); - T ReadFragment(System.IO.MemoryStream input, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, out Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnostic, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null) + T? ReadFragment(System.IO.MemoryStream input, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, out Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnostic, Microsoft.OpenApi.Reader.OpenApiReaderSettings? settings = null) where T : Microsoft.OpenApi.Interfaces.IOpenApiElement; } public interface IOpenApiReferenceHolder : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiSerializable @@ -256,7 +255,7 @@ namespace Microsoft.OpenApi public class JsonPointer { public JsonPointer(string pointer) { } - public Microsoft.OpenApi.JsonPointer ParentPointer { get; } + public Microsoft.OpenApi.JsonPointer? ParentPointer { get; } public string[] Tokens { get; } public override string ToString() { } } @@ -341,101 +340,101 @@ namespace Microsoft.OpenApi.Models.Interfaces { public interface IOpenApiCallback : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable { - System.Collections.Generic.Dictionary PathItems { get; } + System.Collections.Generic.Dictionary? PathItems { get; } } public interface IOpenApiDescribedElement : Microsoft.OpenApi.Interfaces.IOpenApiElement { - string Description { get; set; } + string? Description { get; set; } } public interface IOpenApiExample : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiSummarizedElement { - string ExternalValue { get; } - System.Text.Json.Nodes.JsonNode Value { get; } + string? ExternalValue { get; } + System.Text.Json.Nodes.JsonNode? Value { get; } } public interface IOpenApiHeader : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement { bool AllowEmptyValue { get; } bool AllowReserved { get; } - System.Collections.Generic.IDictionary Content { get; } + System.Collections.Generic.IDictionary? Content { get; } bool Deprecated { get; } - System.Text.Json.Nodes.JsonNode Example { get; } - System.Collections.Generic.IDictionary Examples { get; } + System.Text.Json.Nodes.JsonNode? Example { get; } + System.Collections.Generic.IDictionary? Examples { get; } bool Explode { get; } bool Required { get; } - Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema Schema { get; } + Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? Schema { get; } Microsoft.OpenApi.Models.ParameterStyle? Style { get; } } public interface IOpenApiLink : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement { - string OperationId { get; } - string OperationRef { get; } - System.Collections.Generic.IDictionary Parameters { get; } - Microsoft.OpenApi.Models.RuntimeExpressionAnyWrapper RequestBody { get; } - Microsoft.OpenApi.Models.OpenApiServer Server { get; } + string? OperationId { get; } + string? OperationRef { get; } + System.Collections.Generic.IDictionary? Parameters { get; } + Microsoft.OpenApi.Models.RuntimeExpressionAnyWrapper? RequestBody { get; } + Microsoft.OpenApi.Models.OpenApiServer? Server { get; } } public interface IOpenApiParameter : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement { bool AllowEmptyValue { get; } bool AllowReserved { get; } - System.Collections.Generic.IDictionary Content { get; } + System.Collections.Generic.IDictionary? Content { get; } bool Deprecated { get; } - System.Text.Json.Nodes.JsonNode Example { get; } - System.Collections.Generic.IDictionary Examples { get; } + System.Text.Json.Nodes.JsonNode? Example { get; } + System.Collections.Generic.IDictionary? Examples { get; } bool Explode { get; } Microsoft.OpenApi.Models.ParameterLocation? In { get; } - string Name { get; } + string? Name { get; } bool Required { get; } - Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema Schema { get; } + Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? Schema { get; } Microsoft.OpenApi.Models.ParameterStyle? Style { get; } } public interface IOpenApiPathItem : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiSummarizedElement { - System.Collections.Generic.IDictionary Operations { get; } - System.Collections.Generic.IList Parameters { get; } - System.Collections.Generic.IList Servers { get; } + System.Collections.Generic.IDictionary? Operations { get; } + System.Collections.Generic.IList? Parameters { get; } + System.Collections.Generic.IList? Servers { get; } } public interface IOpenApiReadOnlyDescribedElement : Microsoft.OpenApi.Interfaces.IOpenApiElement { - string Description { get; } + string? Description { get; } } public interface IOpenApiRequestBody : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement { - System.Collections.Generic.IDictionary Content { get; } + System.Collections.Generic.IDictionary? Content { get; } bool Required { get; } - Microsoft.OpenApi.Models.Interfaces.IOpenApiParameter ConvertToBodyParameter(Microsoft.OpenApi.Writers.IOpenApiWriter writer); - System.Collections.Generic.IEnumerable ConvertToFormDataParameters(Microsoft.OpenApi.Writers.IOpenApiWriter writer); + Microsoft.OpenApi.Models.Interfaces.IOpenApiParameter? ConvertToBodyParameter(Microsoft.OpenApi.Writers.IOpenApiWriter writer); + System.Collections.Generic.IEnumerable? ConvertToFormDataParameters(Microsoft.OpenApi.Writers.IOpenApiWriter writer); } public interface IOpenApiResponse : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement { - System.Collections.Generic.IDictionary Content { get; } - System.Collections.Generic.IDictionary Headers { get; } - System.Collections.Generic.IDictionary Links { get; } + System.Collections.Generic.IDictionary? Content { get; } + System.Collections.Generic.IDictionary? Headers { get; } + System.Collections.Generic.IDictionary? Links { get; } } public interface IOpenApiSchema : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement { - Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema AdditionalProperties { get; } + Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? AdditionalProperties { get; } bool AdditionalPropertiesAllowed { get; } - System.Collections.Generic.IList AllOf { get; } - System.Collections.Generic.IDictionary Annotations { get; } - System.Collections.Generic.IList AnyOf { get; } - string Comment { get; } - string Const { get; } - System.Text.Json.Nodes.JsonNode Default { get; } - System.Collections.Generic.IDictionary Definitions { get; } - System.Collections.Generic.IDictionary> DependentRequired { get; } + System.Collections.Generic.IList? AllOf { get; } + System.Collections.Generic.IDictionary? Annotations { get; } + System.Collections.Generic.IList? AnyOf { get; } + string? Comment { get; } + string? Const { get; } + System.Text.Json.Nodes.JsonNode? Default { get; } + System.Collections.Generic.IDictionary? Definitions { get; } + System.Collections.Generic.IDictionary>? DependentRequired { get; } bool Deprecated { get; } - Microsoft.OpenApi.Models.OpenApiDiscriminator Discriminator { get; } - string DynamicAnchor { get; } - string DynamicRef { get; } - System.Collections.Generic.IList Enum { get; } - System.Text.Json.Nodes.JsonNode Example { get; } - System.Collections.Generic.IList Examples { get; } + Microsoft.OpenApi.Models.OpenApiDiscriminator? Discriminator { get; } + string? DynamicAnchor { get; } + string? DynamicRef { get; } + System.Collections.Generic.IList? Enum { get; } + System.Text.Json.Nodes.JsonNode? Example { get; } + System.Collections.Generic.IList? Examples { get; } decimal? ExclusiveMaximum { get; } decimal? ExclusiveMinimum { get; } - Microsoft.OpenApi.Models.OpenApiExternalDocs ExternalDocs { get; } - string Format { get; } - string Id { get; } - Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema Items { get; } + Microsoft.OpenApi.Models.OpenApiExternalDocs? ExternalDocs { get; } + string? Format { get; } + string? Id { get; } + Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? Items { get; } int? MaxItems { get; } int? MaxLength { get; } int? MaxProperties { get; } @@ -445,42 +444,42 @@ namespace Microsoft.OpenApi.Models.Interfaces int? MinProperties { get; } decimal? Minimum { get; } decimal? MultipleOf { get; } - Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema Not { get; } - System.Collections.Generic.IList OneOf { get; } - string Pattern { get; } - System.Collections.Generic.IDictionary PatternProperties { get; } - System.Collections.Generic.IDictionary Properties { get; } + Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? Not { get; } + System.Collections.Generic.IList? OneOf { get; } + string? Pattern { get; } + System.Collections.Generic.IDictionary? PatternProperties { get; } + System.Collections.Generic.IDictionary? Properties { get; } bool ReadOnly { get; } - System.Collections.Generic.ISet Required { get; } - System.Uri Schema { get; } - string Title { get; } + System.Collections.Generic.ISet? Required { get; } + System.Uri? Schema { get; } + string? Title { get; } Microsoft.OpenApi.Models.JsonSchemaType? Type { get; } bool UnEvaluatedProperties { get; } bool UnevaluatedProperties { get; } bool? UniqueItems { get; } - System.Collections.Generic.IDictionary UnrecognizedKeywords { get; } - System.Collections.Generic.IDictionary Vocabulary { get; } + System.Collections.Generic.IDictionary? UnrecognizedKeywords { get; } + System.Collections.Generic.IDictionary? Vocabulary { get; } bool WriteOnly { get; } - Microsoft.OpenApi.Models.OpenApiXml Xml { get; } + Microsoft.OpenApi.Models.OpenApiXml? Xml { get; } } public interface IOpenApiSecurityScheme : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement { - string BearerFormat { get; } - Microsoft.OpenApi.Models.OpenApiOAuthFlows Flows { get; } + string? BearerFormat { get; } + Microsoft.OpenApi.Models.OpenApiOAuthFlows? Flows { get; } Microsoft.OpenApi.Models.ParameterLocation? In { get; } - string Name { get; } - System.Uri OpenIdConnectUrl { get; } - string Scheme { get; } + string? Name { get; } + System.Uri? OpenIdConnectUrl { get; } + string? Scheme { get; } Microsoft.OpenApi.Models.SecuritySchemeType? Type { get; } } public interface IOpenApiSummarizedElement : Microsoft.OpenApi.Interfaces.IOpenApiElement { - string Summary { get; set; } + string? Summary { get; set; } } public interface IOpenApiTag : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiReadOnlyDescribedElement { - Microsoft.OpenApi.Models.OpenApiExternalDocs ExternalDocs { get; } - string Name { get; } + Microsoft.OpenApi.Models.OpenApiExternalDocs? ExternalDocs { get; } + string? Name { get; } } } namespace Microsoft.OpenApi.Models @@ -499,8 +498,8 @@ namespace Microsoft.OpenApi.Models public class OpenApiCallback : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback { public OpenApiCallback() { } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public System.Collections.Generic.Dictionary PathItems { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public System.Collections.Generic.Dictionary? PathItems { get; set; } public void AddPathItem(Microsoft.OpenApi.Expressions.RuntimeExpression expression, Microsoft.OpenApi.Models.Interfaces.IOpenApiPathItem pathItem) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback CreateShallowCopy() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -688,10 +687,10 @@ namespace Microsoft.OpenApi.Models { public OpenApiContact() { } public OpenApiContact(Microsoft.OpenApi.Models.OpenApiContact contact) { } - public string Email { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public string Name { get; set; } - public System.Uri Url { get; set; } + public string? Email { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public string? Name { get; set; } + public System.Uri? Url { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -700,9 +699,9 @@ namespace Microsoft.OpenApi.Models { public OpenApiDiscriminator() { } public OpenApiDiscriminator(Microsoft.OpenApi.Models.OpenApiDiscriminator discriminator) { } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public System.Collections.Generic.IDictionary Mapping { get; set; } - public string PropertyName { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public System.Collections.Generic.IDictionary? Mapping { get; set; } + public string? PropertyName { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -742,10 +741,10 @@ namespace Microsoft.OpenApi.Models public OpenApiEncoding() { } public OpenApiEncoding(Microsoft.OpenApi.Models.OpenApiEncoding encoding) { } public bool? AllowReserved { get; set; } - public string ContentType { get; set; } + public string? ContentType { get; set; } public bool? Explode { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public System.Collections.Generic.IDictionary Headers { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public System.Collections.Generic.IDictionary? Headers { get; set; } public Microsoft.OpenApi.Models.ParameterStyle? Style { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -755,19 +754,19 @@ namespace Microsoft.OpenApi.Models { public OpenApiError(Microsoft.OpenApi.Exceptions.OpenApiException exception) { } public OpenApiError(Microsoft.OpenApi.Models.OpenApiError error) { } - public OpenApiError(string pointer, string message) { } + public OpenApiError(string? pointer, string message) { } public string Message { get; set; } - public string Pointer { get; set; } + public string? Pointer { get; set; } public override string ToString() { } } public class OpenApiExample : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiExample, Microsoft.OpenApi.Models.Interfaces.IOpenApiSummarizedElement { public OpenApiExample() { } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public string ExternalValue { get; set; } - public string Summary { get; set; } - public System.Text.Json.Nodes.JsonNode Value { get; set; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public string? ExternalValue { get; set; } + public string? Summary { get; set; } + public System.Text.Json.Nodes.JsonNode? Value { get; set; } public Microsoft.OpenApi.Models.Interfaces.IOpenApiExample CreateShallowCopy() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -777,8 +776,8 @@ namespace Microsoft.OpenApi.Models where T : Microsoft.OpenApi.Interfaces.IOpenApiSerializable { protected OpenApiExtensibleDictionary() { } - protected OpenApiExtensibleDictionary(System.Collections.Generic.Dictionary dictionary, System.Collections.Generic.IDictionary extensions = null) { } - public System.Collections.Generic.IDictionary Extensions { get; set; } + protected OpenApiExtensibleDictionary(System.Collections.Generic.Dictionary dictionary, System.Collections.Generic.IDictionary? extensions = null) { } + public System.Collections.Generic.IDictionary? Extensions { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -787,9 +786,9 @@ namespace Microsoft.OpenApi.Models { public OpenApiExternalDocs() { } public OpenApiExternalDocs(Microsoft.OpenApi.Models.OpenApiExternalDocs externalDocs) { } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public System.Uri Url { get; set; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public System.Uri? Url { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -799,15 +798,15 @@ namespace Microsoft.OpenApi.Models public OpenApiHeader() { } public bool AllowEmptyValue { get; set; } public bool AllowReserved { get; set; } - public System.Collections.Generic.IDictionary Content { get; set; } + public System.Collections.Generic.IDictionary? Content { get; set; } public bool Deprecated { get; set; } - public string Description { get; set; } - public System.Text.Json.Nodes.JsonNode Example { get; set; } - public System.Collections.Generic.IDictionary Examples { get; set; } + public string? Description { get; set; } + public System.Text.Json.Nodes.JsonNode? Example { get; set; } + public System.Collections.Generic.IDictionary? Examples { get; set; } public bool Explode { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } public bool Required { get; set; } - public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema Schema { get; set; } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? Schema { get; set; } public Microsoft.OpenApi.Models.ParameterStyle? Style { get; set; } public Microsoft.OpenApi.Models.Interfaces.IOpenApiHeader CreateShallowCopy() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -818,14 +817,14 @@ namespace Microsoft.OpenApi.Models { public OpenApiInfo() { } public OpenApiInfo(Microsoft.OpenApi.Models.OpenApiInfo info) { } - public Microsoft.OpenApi.Models.OpenApiContact Contact { get; set; } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public Microsoft.OpenApi.Models.OpenApiLicense License { get; set; } - public string Summary { get; set; } - public System.Uri TermsOfService { get; set; } - public string Title { get; set; } - public string Version { get; set; } + public Microsoft.OpenApi.Models.OpenApiContact? Contact { get; set; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public Microsoft.OpenApi.Models.OpenApiLicense? License { get; set; } + public string? Summary { get; set; } + public System.Uri? TermsOfService { get; set; } + public string? Title { get; set; } + public string? Version { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -834,10 +833,10 @@ namespace Microsoft.OpenApi.Models { public OpenApiLicense() { } public OpenApiLicense(Microsoft.OpenApi.Models.OpenApiLicense license) { } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public string Identifier { get; set; } - public string Name { get; set; } - public System.Uri Url { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public string? Identifier { get; set; } + public string? Name { get; set; } + public System.Uri? Url { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -845,13 +844,13 @@ namespace Microsoft.OpenApi.Models public class OpenApiLink : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiLink { public OpenApiLink() { } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public string OperationId { get; set; } - public string OperationRef { get; set; } - public System.Collections.Generic.IDictionary Parameters { get; set; } - public Microsoft.OpenApi.Models.RuntimeExpressionAnyWrapper RequestBody { get; set; } - public Microsoft.OpenApi.Models.OpenApiServer Server { get; set; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public string? OperationId { get; set; } + public string? OperationRef { get; set; } + public System.Collections.Generic.IDictionary? Parameters { get; set; } + public Microsoft.OpenApi.Models.RuntimeExpressionAnyWrapper? RequestBody { get; set; } + public Microsoft.OpenApi.Models.OpenApiServer? Server { get; set; } public Microsoft.OpenApi.Models.Interfaces.IOpenApiLink CreateShallowCopy() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -874,11 +873,11 @@ namespace Microsoft.OpenApi.Models { public OpenApiOAuthFlow() { } public OpenApiOAuthFlow(Microsoft.OpenApi.Models.OpenApiOAuthFlow oAuthFlow) { } - public System.Uri AuthorizationUrl { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public System.Uri RefreshUrl { get; set; } - public System.Collections.Generic.IDictionary Scopes { get; set; } - public System.Uri TokenUrl { get; set; } + public System.Uri? AuthorizationUrl { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public System.Uri? RefreshUrl { get; set; } + public System.Collections.Generic.IDictionary? Scopes { get; set; } + public System.Uri? TokenUrl { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -887,11 +886,11 @@ namespace Microsoft.OpenApi.Models { public OpenApiOAuthFlows() { } public OpenApiOAuthFlows(Microsoft.OpenApi.Models.OpenApiOAuthFlows oAuthFlows) { } - public Microsoft.OpenApi.Models.OpenApiOAuthFlow AuthorizationCode { get; set; } - public Microsoft.OpenApi.Models.OpenApiOAuthFlow ClientCredentials { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public Microsoft.OpenApi.Models.OpenApiOAuthFlow Implicit { get; set; } - public Microsoft.OpenApi.Models.OpenApiOAuthFlow Password { get; set; } + public Microsoft.OpenApi.Models.OpenApiOAuthFlow? AuthorizationCode { get; set; } + public Microsoft.OpenApi.Models.OpenApiOAuthFlow? ClientCredentials { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public Microsoft.OpenApi.Models.OpenApiOAuthFlow? Implicit { get; set; } + public Microsoft.OpenApi.Models.OpenApiOAuthFlow? Password { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -924,17 +923,17 @@ namespace Microsoft.OpenApi.Models public OpenApiParameter() { } public bool AllowEmptyValue { get; set; } public bool AllowReserved { get; set; } - public System.Collections.Generic.IDictionary Content { get; set; } + public System.Collections.Generic.IDictionary? Content { get; set; } public bool Deprecated { get; set; } - public string Description { get; set; } - public System.Text.Json.Nodes.JsonNode Example { get; set; } - public System.Collections.Generic.IDictionary Examples { get; set; } + public string? Description { get; set; } + public System.Text.Json.Nodes.JsonNode? Example { get; set; } + public System.Collections.Generic.IDictionary? Examples { get; set; } public bool Explode { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } public Microsoft.OpenApi.Models.ParameterLocation? In { get; set; } - public string Name { get; set; } + public string? Name { get; set; } public bool Required { get; set; } - public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema Schema { get; set; } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? Schema { get; set; } public Microsoft.OpenApi.Models.ParameterStyle? Style { get; set; } public Microsoft.OpenApi.Models.Interfaces.IOpenApiParameter CreateShallowCopy() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -944,12 +943,12 @@ namespace Microsoft.OpenApi.Models public class OpenApiPathItem : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiPathItem, Microsoft.OpenApi.Models.Interfaces.IOpenApiSummarizedElement { public OpenApiPathItem() { } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public System.Collections.Generic.IDictionary Operations { get; set; } - public System.Collections.Generic.IList Parameters { get; set; } - public System.Collections.Generic.IList Servers { get; set; } - public string Summary { get; set; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public System.Collections.Generic.IDictionary? Operations { get; set; } + public System.Collections.Generic.IList? Parameters { get; set; } + public System.Collections.Generic.IList? Servers { get; set; } + public string? Summary { get; set; } public void AddOperation(System.Net.Http.HttpMethod operationType, Microsoft.OpenApi.Models.OpenApiOperation operation) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiPathItem CreateShallowCopy() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -965,17 +964,17 @@ namespace Microsoft.OpenApi.Models { public OpenApiReference() { } public OpenApiReference(Microsoft.OpenApi.Models.OpenApiReference reference) { } - public string Description { get; set; } - public string ExternalResource { get; init; } - public Microsoft.OpenApi.Models.OpenApiDocument HostDocument { get; init; } - public string Id { get; init; } + public string? Description { get; set; } + public string? ExternalResource { get; init; } + public Microsoft.OpenApi.Models.OpenApiDocument? HostDocument { get; init; } + public string? Id { get; init; } public bool IsExternal { get; } public bool IsFragment { get; init; } public bool IsLocal { get; } - public string ReferenceV2 { get; } - public string ReferenceV3 { get; } - public string Summary { get; set; } - public Microsoft.OpenApi.Models.ReferenceType? Type { get; init; } + public string? ReferenceV2 { get; } + public string? ReferenceV3 { get; } + public string? Summary { get; set; } + public Microsoft.OpenApi.Models.ReferenceType Type { get; init; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -983,9 +982,9 @@ namespace Microsoft.OpenApi.Models public class OpenApiRequestBody : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiRequestBody { public OpenApiRequestBody() { } - public System.Collections.Generic.IDictionary Content { get; set; } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } + public System.Collections.Generic.IDictionary? Content { get; set; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } public bool Required { get; set; } public Microsoft.OpenApi.Models.Interfaces.IOpenApiParameter ConvertToBodyParameter(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public System.Collections.Generic.IEnumerable ConvertToFormDataParameters(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -997,11 +996,11 @@ namespace Microsoft.OpenApi.Models public class OpenApiResponse : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiResponse { public OpenApiResponse() { } - public System.Collections.Generic.IDictionary Content { get; set; } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public System.Collections.Generic.IDictionary Headers { get; set; } - public System.Collections.Generic.IDictionary Links { get; set; } + public System.Collections.Generic.IDictionary? Content { get; set; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public System.Collections.Generic.IDictionary? Headers { get; set; } + public System.Collections.Generic.IDictionary? Links { get; set; } public Microsoft.OpenApi.Models.Interfaces.IOpenApiResponse CreateShallowCopy() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1015,31 +1014,31 @@ namespace Microsoft.OpenApi.Models public class OpenApiSchema : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema { public OpenApiSchema() { } - public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema AdditionalProperties { get; set; } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? AdditionalProperties { get; set; } public bool AdditionalPropertiesAllowed { get; set; } - public System.Collections.Generic.IList AllOf { get; set; } - public System.Collections.Generic.IDictionary Annotations { get; set; } - public System.Collections.Generic.IList AnyOf { get; set; } - public string Comment { get; set; } - public string Const { get; set; } - public System.Text.Json.Nodes.JsonNode Default { get; set; } - public System.Collections.Generic.IDictionary Definitions { get; set; } - public System.Collections.Generic.IDictionary> DependentRequired { get; set; } + public System.Collections.Generic.IList? AllOf { get; set; } + public System.Collections.Generic.IDictionary? Annotations { get; set; } + public System.Collections.Generic.IList? AnyOf { get; set; } + public string? Comment { get; set; } + public string? Const { get; set; } + public System.Text.Json.Nodes.JsonNode? Default { get; set; } + public System.Collections.Generic.IDictionary? Definitions { get; set; } + public System.Collections.Generic.IDictionary>? DependentRequired { get; set; } public bool Deprecated { get; set; } - public string Description { get; set; } - public Microsoft.OpenApi.Models.OpenApiDiscriminator Discriminator { get; set; } - public string DynamicAnchor { get; set; } - public string DynamicRef { get; set; } - public System.Collections.Generic.IList Enum { get; set; } - public System.Text.Json.Nodes.JsonNode Example { get; set; } - public System.Collections.Generic.IList Examples { get; set; } + public string? Description { get; set; } + public Microsoft.OpenApi.Models.OpenApiDiscriminator? Discriminator { get; set; } + public string? DynamicAnchor { get; set; } + public string? DynamicRef { get; set; } + public System.Collections.Generic.IList? Enum { get; set; } + public System.Text.Json.Nodes.JsonNode? Example { get; set; } + public System.Collections.Generic.IList? Examples { get; set; } public decimal? ExclusiveMaximum { get; set; } public decimal? ExclusiveMinimum { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public Microsoft.OpenApi.Models.OpenApiExternalDocs ExternalDocs { get; set; } - public string Format { get; set; } - public string Id { get; set; } - public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema Items { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public Microsoft.OpenApi.Models.OpenApiExternalDocs? ExternalDocs { get; set; } + public string? Format { get; set; } + public string? Id { get; set; } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? Items { get; set; } public int? MaxItems { get; set; } public int? MaxLength { get; set; } public int? MaxProperties { get; set; } @@ -1049,23 +1048,23 @@ namespace Microsoft.OpenApi.Models public int? MinProperties { get; set; } public decimal? Minimum { get; set; } public decimal? MultipleOf { get; set; } - public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema Not { get; set; } - public System.Collections.Generic.IList OneOf { get; set; } - public string Pattern { get; set; } - public System.Collections.Generic.IDictionary PatternProperties { get; set; } - public System.Collections.Generic.IDictionary Properties { get; set; } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? Not { get; set; } + public System.Collections.Generic.IList? OneOf { get; set; } + public string? Pattern { get; set; } + public System.Collections.Generic.IDictionary? PatternProperties { get; set; } + public System.Collections.Generic.IDictionary? Properties { get; set; } public bool ReadOnly { get; set; } - public System.Collections.Generic.ISet Required { get; set; } - public System.Uri Schema { get; set; } - public string Title { get; set; } + public System.Collections.Generic.ISet? Required { get; set; } + public System.Uri? Schema { get; set; } + public string? Title { get; set; } public Microsoft.OpenApi.Models.JsonSchemaType? Type { get; set; } public bool UnEvaluatedProperties { get; set; } public bool UnevaluatedProperties { get; set; } public bool? UniqueItems { get; set; } - public System.Collections.Generic.IDictionary UnrecognizedKeywords { get; set; } - public System.Collections.Generic.IDictionary Vocabulary { get; set; } + public System.Collections.Generic.IDictionary? UnrecognizedKeywords { get; set; } + public System.Collections.Generic.IDictionary? Vocabulary { get; set; } public bool WriteOnly { get; set; } - public Microsoft.OpenApi.Models.OpenApiXml Xml { get; set; } + public Microsoft.OpenApi.Models.OpenApiXml? Xml { get; set; } public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema CreateShallowCopy() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1081,14 +1080,14 @@ namespace Microsoft.OpenApi.Models public class OpenApiSecurityScheme : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiSecurityScheme { public OpenApiSecurityScheme() { } - public string BearerFormat { get; set; } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public Microsoft.OpenApi.Models.OpenApiOAuthFlows Flows { get; set; } + public string? BearerFormat { get; set; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public Microsoft.OpenApi.Models.OpenApiOAuthFlows? Flows { get; set; } public Microsoft.OpenApi.Models.ParameterLocation? In { get; set; } - public string Name { get; set; } - public System.Uri OpenIdConnectUrl { get; set; } - public string Scheme { get; set; } + public string? Name { get; set; } + public System.Uri? OpenIdConnectUrl { get; set; } + public string? Scheme { get; set; } public Microsoft.OpenApi.Models.SecuritySchemeType? Type { get; set; } public Microsoft.OpenApi.Models.Interfaces.IOpenApiSecurityScheme CreateShallowCopy() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1099,10 +1098,10 @@ namespace Microsoft.OpenApi.Models { public OpenApiServer() { } public OpenApiServer(Microsoft.OpenApi.Models.OpenApiServer server) { } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public string Url { get; set; } - public System.Collections.Generic.IDictionary Variables { get; set; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public string? Url { get; set; } + public System.Collections.Generic.IDictionary? Variables { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1111,10 +1110,10 @@ namespace Microsoft.OpenApi.Models { public OpenApiServerVariable() { } public OpenApiServerVariable(Microsoft.OpenApi.Models.OpenApiServerVariable serverVariable) { } - public string Default { get; set; } - public string Description { get; set; } - public System.Collections.Generic.List Enum { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } + public string? Default { get; set; } + public string? Description { get; set; } + public System.Collections.Generic.List? Enum { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1122,10 +1121,10 @@ namespace Microsoft.OpenApi.Models public class OpenApiTag : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiReadOnlyDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiTag { public OpenApiTag() { } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public Microsoft.OpenApi.Models.OpenApiExternalDocs ExternalDocs { get; set; } - public string Name { get; set; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public Microsoft.OpenApi.Models.OpenApiExternalDocs? ExternalDocs { get; set; } + public string? Name { get; set; } public Microsoft.OpenApi.Models.Interfaces.IOpenApiTag CreateShallowCopy() { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1136,10 +1135,10 @@ namespace Microsoft.OpenApi.Models public OpenApiXml() { } public OpenApiXml(Microsoft.OpenApi.Models.OpenApiXml xml) { } public bool Attribute { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; set; } - public string Name { get; set; } - public System.Uri Namespace { get; set; } - public string Prefix { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; set; } + public string? Name { get; set; } + public System.Uri? Namespace { get; set; } + public string? Prefix { get; set; } public bool Wrapped { get; set; } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1202,8 +1201,8 @@ namespace Microsoft.OpenApi.Models { public RuntimeExpressionAnyWrapper() { } public RuntimeExpressionAnyWrapper(Microsoft.OpenApi.Models.RuntimeExpressionAnyWrapper runtimeExpressionAnyWrapper) { } - public System.Text.Json.Nodes.JsonNode Any { get; set; } - public Microsoft.OpenApi.Expressions.RuntimeExpression Expression { get; set; } + public System.Text.Json.Nodes.JsonNode? Any { get; set; } + public Microsoft.OpenApi.Expressions.RuntimeExpression? Expression { get; set; } public void WriteValue(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } public enum SecuritySchemeType @@ -1225,7 +1224,7 @@ namespace Microsoft.OpenApi.Models.References where V : Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable { protected BaseOpenApiReferenceHolder(Microsoft.OpenApi.Models.References.BaseOpenApiReferenceHolder source) { } - protected BaseOpenApiReferenceHolder(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument, Microsoft.OpenApi.Models.ReferenceType referenceType, string externalResource) { } + protected BaseOpenApiReferenceHolder(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument? hostDocument, Microsoft.OpenApi.Models.ReferenceType referenceType, string? externalResource) { } public T RecursiveTarget { get; } public Microsoft.OpenApi.Models.OpenApiReference Reference { get; init; } public virtual V Target { get; } @@ -1237,142 +1236,142 @@ namespace Microsoft.OpenApi.Models.References } public class OpenApiCallbackReference : Microsoft.OpenApi.Models.References.BaseOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback { - public OpenApiCallbackReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument = null, string externalResource = null) { } - public System.Collections.Generic.IDictionary Extensions { get; } - public System.Collections.Generic.Dictionary PathItems { get; } + public OpenApiCallbackReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument? hostDocument = null, string? externalResource = null) { } + public System.Collections.Generic.IDictionary? Extensions { get; } + public System.Collections.Generic.Dictionary? PathItems { get; } public override Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback source) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback CreateShallowCopy() { } public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } public class OpenApiExampleReference : Microsoft.OpenApi.Models.References.BaseOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiExample, Microsoft.OpenApi.Models.Interfaces.IOpenApiSummarizedElement { - public OpenApiExampleReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument = null, string externalResource = null) { } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; } - public string ExternalValue { get; } - public string Summary { get; set; } - public System.Text.Json.Nodes.JsonNode Value { get; } + public OpenApiExampleReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument? hostDocument = null, string? externalResource = null) { } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; } + public string? ExternalValue { get; } + public string? Summary { get; set; } + public System.Text.Json.Nodes.JsonNode? Value { get; } public override Microsoft.OpenApi.Models.Interfaces.IOpenApiExample CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiExample source) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiExample CreateShallowCopy() { } public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } public class OpenApiHeaderReference : Microsoft.OpenApi.Models.References.BaseOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiHeader { - public OpenApiHeaderReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument = null, string externalResource = null) { } + public OpenApiHeaderReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument? hostDocument = null, string? externalResource = null) { } public bool AllowEmptyValue { get; } public bool AllowReserved { get; } - public System.Collections.Generic.IDictionary Content { get; } + public System.Collections.Generic.IDictionary? Content { get; } public bool Deprecated { get; } - public string Description { get; set; } - public System.Text.Json.Nodes.JsonNode Example { get; } - public System.Collections.Generic.IDictionary Examples { get; } + public string? Description { get; set; } + public System.Text.Json.Nodes.JsonNode? Example { get; } + public System.Collections.Generic.IDictionary? Examples { get; } public bool Explode { get; } - public System.Collections.Generic.IDictionary Extensions { get; } + public System.Collections.Generic.IDictionary? Extensions { get; } public bool Required { get; } - public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema Schema { get; } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? Schema { get; } public Microsoft.OpenApi.Models.ParameterStyle? Style { get; } public override Microsoft.OpenApi.Models.Interfaces.IOpenApiHeader CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiHeader source) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiHeader CreateShallowCopy() { } } public class OpenApiLinkReference : Microsoft.OpenApi.Models.References.BaseOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiLink { - public OpenApiLinkReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument = null, string externalResource = null) { } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; } - public string OperationId { get; } - public string OperationRef { get; } - public System.Collections.Generic.IDictionary Parameters { get; } - public Microsoft.OpenApi.Models.RuntimeExpressionAnyWrapper RequestBody { get; } - public Microsoft.OpenApi.Models.OpenApiServer Server { get; } + public OpenApiLinkReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument? hostDocument = null, string? externalResource = null) { } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; } + public string? OperationId { get; } + public string? OperationRef { get; } + public System.Collections.Generic.IDictionary? Parameters { get; } + public Microsoft.OpenApi.Models.RuntimeExpressionAnyWrapper? RequestBody { get; } + public Microsoft.OpenApi.Models.OpenApiServer? Server { get; } public override Microsoft.OpenApi.Models.Interfaces.IOpenApiLink CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiLink source) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiLink CreateShallowCopy() { } public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } public class OpenApiParameterReference : Microsoft.OpenApi.Models.References.BaseOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiParameter { - public OpenApiParameterReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument = null, string externalResource = null) { } + public OpenApiParameterReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument? hostDocument = null, string? externalResource = null) { } public bool AllowEmptyValue { get; } public bool AllowReserved { get; } - public System.Collections.Generic.IDictionary Content { get; } + public System.Collections.Generic.IDictionary? Content { get; } public bool Deprecated { get; } - public string Description { get; set; } - public System.Text.Json.Nodes.JsonNode Example { get; } - public System.Collections.Generic.IDictionary Examples { get; } + public string? Description { get; set; } + public System.Text.Json.Nodes.JsonNode? Example { get; } + public System.Collections.Generic.IDictionary? Examples { get; } public bool Explode { get; } - public System.Collections.Generic.IDictionary Extensions { get; } + public System.Collections.Generic.IDictionary? Extensions { get; } public Microsoft.OpenApi.Models.ParameterLocation? In { get; } - public string Name { get; } + public string? Name { get; } public bool Required { get; } - public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema Schema { get; } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? Schema { get; } public Microsoft.OpenApi.Models.ParameterStyle? Style { get; } public override Microsoft.OpenApi.Models.Interfaces.IOpenApiParameter CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiParameter source) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiParameter CreateShallowCopy() { } } public class OpenApiPathItemReference : Microsoft.OpenApi.Models.References.BaseOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiPathItem, Microsoft.OpenApi.Models.Interfaces.IOpenApiSummarizedElement { - public OpenApiPathItemReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument = null, string externalResource = null) { } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; } - public System.Collections.Generic.IDictionary Operations { get; } - public System.Collections.Generic.IList Parameters { get; } - public System.Collections.Generic.IList Servers { get; } - public string Summary { get; set; } + public OpenApiPathItemReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument? hostDocument = null, string? externalResource = null) { } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; } + public System.Collections.Generic.IDictionary? Operations { get; } + public System.Collections.Generic.IList? Parameters { get; } + public System.Collections.Generic.IList? Servers { get; } + public string? Summary { get; set; } public override Microsoft.OpenApi.Models.Interfaces.IOpenApiPathItem CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiPathItem source) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiPathItem CreateShallowCopy() { } public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } public class OpenApiRequestBodyReference : Microsoft.OpenApi.Models.References.BaseOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiRequestBody { - public OpenApiRequestBodyReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument = null, string externalResource = null) { } - public System.Collections.Generic.IDictionary Content { get; } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; } + public OpenApiRequestBodyReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument? hostDocument = null, string? externalResource = null) { } + public System.Collections.Generic.IDictionary? Content { get; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; } public bool Required { get; } - public Microsoft.OpenApi.Models.Interfaces.IOpenApiParameter ConvertToBodyParameter(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } - public System.Collections.Generic.IEnumerable ConvertToFormDataParameters(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiParameter? ConvertToBodyParameter(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public System.Collections.Generic.IEnumerable? ConvertToFormDataParameters(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public override Microsoft.OpenApi.Models.Interfaces.IOpenApiRequestBody CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiRequestBody source) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiRequestBody CreateShallowCopy() { } public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } public class OpenApiResponseReference : Microsoft.OpenApi.Models.References.BaseOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiResponse { - public OpenApiResponseReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument = null, string externalResource = null) { } - public System.Collections.Generic.IDictionary Content { get; } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; } - public System.Collections.Generic.IDictionary Headers { get; } - public System.Collections.Generic.IDictionary Links { get; } + public OpenApiResponseReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument? hostDocument = null, string? externalResource = null) { } + public System.Collections.Generic.IDictionary? Content { get; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; } + public System.Collections.Generic.IDictionary? Headers { get; } + public System.Collections.Generic.IDictionary? Links { get; } public override Microsoft.OpenApi.Models.Interfaces.IOpenApiResponse CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiResponse source) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiResponse CreateShallowCopy() { } } public class OpenApiSchemaReference : Microsoft.OpenApi.Models.References.BaseOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema { - public OpenApiSchemaReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument = null, string externalResource = null) { } - public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema AdditionalProperties { get; } + public OpenApiSchemaReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument? hostDocument = null, string? externalResource = null) { } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? AdditionalProperties { get; } public bool AdditionalPropertiesAllowed { get; } - public System.Collections.Generic.IList AllOf { get; } - public System.Collections.Generic.IDictionary Annotations { get; } - public System.Collections.Generic.IList AnyOf { get; } - public string Comment { get; } - public string Const { get; } - public System.Text.Json.Nodes.JsonNode Default { get; } - public System.Collections.Generic.IDictionary Definitions { get; } - public System.Collections.Generic.IDictionary> DependentRequired { get; } + public System.Collections.Generic.IList? AllOf { get; } + public System.Collections.Generic.IDictionary? Annotations { get; } + public System.Collections.Generic.IList? AnyOf { get; } + public string? Comment { get; } + public string? Const { get; } + public System.Text.Json.Nodes.JsonNode? Default { get; } + public System.Collections.Generic.IDictionary? Definitions { get; } + public System.Collections.Generic.IDictionary>? DependentRequired { get; } public bool Deprecated { get; } - public string Description { get; set; } - public Microsoft.OpenApi.Models.OpenApiDiscriminator Discriminator { get; } - public string DynamicAnchor { get; } - public string DynamicRef { get; } - public System.Collections.Generic.IList Enum { get; } - public System.Text.Json.Nodes.JsonNode Example { get; } - public System.Collections.Generic.IList Examples { get; } + public string? Description { get; set; } + public Microsoft.OpenApi.Models.OpenApiDiscriminator? Discriminator { get; } + public string? DynamicAnchor { get; } + public string? DynamicRef { get; } + public System.Collections.Generic.IList? Enum { get; } + public System.Text.Json.Nodes.JsonNode? Example { get; } + public System.Collections.Generic.IList? Examples { get; } public decimal? ExclusiveMaximum { get; } public decimal? ExclusiveMinimum { get; } - public System.Collections.Generic.IDictionary Extensions { get; } - public Microsoft.OpenApi.Models.OpenApiExternalDocs ExternalDocs { get; } - public string Format { get; } - public string Id { get; } - public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema Items { get; } + public System.Collections.Generic.IDictionary? Extensions { get; } + public Microsoft.OpenApi.Models.OpenApiExternalDocs? ExternalDocs { get; } + public string? Format { get; } + public string? Id { get; } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? Items { get; } public int? MaxItems { get; } public int? MaxLength { get; } public int? MaxProperties { get; } @@ -1382,23 +1381,23 @@ namespace Microsoft.OpenApi.Models.References public int? MinProperties { get; } public decimal? Minimum { get; } public decimal? MultipleOf { get; } - public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema Not { get; } - public System.Collections.Generic.IList OneOf { get; } - public string Pattern { get; } - public System.Collections.Generic.IDictionary PatternProperties { get; } - public System.Collections.Generic.IDictionary Properties { get; } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema? Not { get; } + public System.Collections.Generic.IList? OneOf { get; } + public string? Pattern { get; } + public System.Collections.Generic.IDictionary? PatternProperties { get; } + public System.Collections.Generic.IDictionary? Properties { get; } public bool ReadOnly { get; } - public System.Collections.Generic.ISet Required { get; } - public System.Uri Schema { get; } - public string Title { get; } + public System.Collections.Generic.ISet? Required { get; } + public System.Uri? Schema { get; } + public string? Title { get; } public Microsoft.OpenApi.Models.JsonSchemaType? Type { get; } public bool UnEvaluatedProperties { get; } public bool UnevaluatedProperties { get; } public bool? UniqueItems { get; } - public System.Collections.Generic.IDictionary UnrecognizedKeywords { get; } - public System.Collections.Generic.IDictionary Vocabulary { get; } + public System.Collections.Generic.IDictionary? UnrecognizedKeywords { get; } + public System.Collections.Generic.IDictionary? Vocabulary { get; } public bool WriteOnly { get; } - public Microsoft.OpenApi.Models.OpenApiXml Xml { get; } + public Microsoft.OpenApi.Models.OpenApiXml? Xml { get; } public override Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema source) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema CreateShallowCopy() { } public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1407,27 +1406,27 @@ namespace Microsoft.OpenApi.Models.References } public class OpenApiSecuritySchemeReference : Microsoft.OpenApi.Models.References.BaseOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiSecurityScheme { - public OpenApiSecuritySchemeReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument = null, string externalResource = null) { } - public string BearerFormat { get; } - public string Description { get; set; } - public System.Collections.Generic.IDictionary Extensions { get; } - public Microsoft.OpenApi.Models.OpenApiOAuthFlows Flows { get; } + public OpenApiSecuritySchemeReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument? hostDocument = null, string? externalResource = null) { } + public string? BearerFormat { get; } + public string? Description { get; set; } + public System.Collections.Generic.IDictionary? Extensions { get; } + public Microsoft.OpenApi.Models.OpenApiOAuthFlows? Flows { get; } public Microsoft.OpenApi.Models.ParameterLocation? In { get; } - public string Name { get; } - public System.Uri OpenIdConnectUrl { get; } - public string Scheme { get; } + public string? Name { get; } + public System.Uri? OpenIdConnectUrl { get; } + public string? Scheme { get; } public Microsoft.OpenApi.Models.SecuritySchemeType? Type { get; } public override Microsoft.OpenApi.Models.Interfaces.IOpenApiSecurityScheme CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiSecurityScheme source) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiSecurityScheme CreateShallowCopy() { } } public class OpenApiTagReference : Microsoft.OpenApi.Models.References.BaseOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Interfaces.IShallowCopyable, Microsoft.OpenApi.Models.Interfaces.IOpenApiReadOnlyDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiTag { - public OpenApiTagReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument = null, string externalResource = null) { } - public string Description { get; } - public System.Collections.Generic.IDictionary Extensions { get; } - public Microsoft.OpenApi.Models.OpenApiExternalDocs ExternalDocs { get; } - public string Name { get; } - public override Microsoft.OpenApi.Models.Interfaces.IOpenApiTag Target { get; } + public OpenApiTagReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument? hostDocument = null, string? externalResource = null) { } + public string? Description { get; } + public System.Collections.Generic.IDictionary? Extensions { get; } + public Microsoft.OpenApi.Models.OpenApiExternalDocs? ExternalDocs { get; } + public string? Name { get; } + public override Microsoft.OpenApi.Models.Interfaces.IOpenApiTag? Target { get; } public override Microsoft.OpenApi.Models.Interfaces.IOpenApiTag CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiTag source) { } public Microsoft.OpenApi.Models.Interfaces.IOpenApiTag CreateShallowCopy() { } } @@ -1440,7 +1439,7 @@ namespace Microsoft.OpenApi.Reader public System.Collections.Generic.IList Errors { get; set; } public Microsoft.OpenApi.OpenApiSpecVersion SpecificationVersion { get; set; } public System.Collections.Generic.IList Warnings { get; set; } - public void AppendDiagnostic(Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnosticToAdd, string fileNameToAdd = null) { } + public void AppendDiagnostic(Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnosticToAdd, string? fileNameToAdd = null) { } } public class OpenApiJsonReader : Microsoft.OpenApi.Interfaces.IOpenApiReader { @@ -1448,33 +1447,33 @@ namespace Microsoft.OpenApi.Reader public Microsoft.OpenApi.Reader.ReadResult Read(System.IO.MemoryStream input, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings) { } public Microsoft.OpenApi.Reader.ReadResult Read(System.Text.Json.Nodes.JsonNode jsonNode, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings) { } public System.Threading.Tasks.Task ReadAsync(System.IO.Stream input, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings, System.Threading.CancellationToken cancellationToken = default) { } - public T ReadFragment(System.IO.MemoryStream input, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, out Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnostic, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null) + public T? ReadFragment(System.IO.MemoryStream input, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, out Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnostic, Microsoft.OpenApi.Reader.OpenApiReaderSettings? settings = null) where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { } - public T ReadFragment(System.Text.Json.Nodes.JsonNode input, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, out Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnostic, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null) + public T? ReadFragment(System.Text.Json.Nodes.JsonNode input, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, out Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnostic, Microsoft.OpenApi.Reader.OpenApiReaderSettings? settings = null) where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { } } public static class OpenApiModelFactory { - public static Microsoft.OpenApi.Reader.ReadResult Load(System.IO.MemoryStream stream, string format = null, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null) { } - public static T Load(System.IO.MemoryStream input, Microsoft.OpenApi.OpenApiSpecVersion version, string format, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, out Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnostic, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null) + public static Microsoft.OpenApi.Reader.ReadResult Load(System.IO.MemoryStream stream, string? format = null, Microsoft.OpenApi.Reader.OpenApiReaderSettings? settings = null) { } + public static T? Load(System.IO.MemoryStream input, Microsoft.OpenApi.OpenApiSpecVersion version, string? format, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, out Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnostic, Microsoft.OpenApi.Reader.OpenApiReaderSettings? settings = null) where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { } - public static System.Threading.Tasks.Task LoadAsync(string url, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null, System.Threading.CancellationToken token = default) { } - public static System.Threading.Tasks.Task LoadAsync(System.IO.Stream input, string format = null, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null, System.Threading.CancellationToken cancellationToken = default) { } - public static System.Threading.Tasks.Task LoadAsync(string url, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null, System.Threading.CancellationToken token = default) + public static System.Threading.Tasks.Task LoadAsync(string url, Microsoft.OpenApi.Reader.OpenApiReaderSettings? settings = null, System.Threading.CancellationToken token = default) { } + public static System.Threading.Tasks.Task LoadAsync(System.IO.Stream input, string? format = null, Microsoft.OpenApi.Reader.OpenApiReaderSettings? settings = null, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.Task LoadAsync(string url, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, Microsoft.OpenApi.Reader.OpenApiReaderSettings? settings = null, System.Threading.CancellationToken token = default) where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { } - public static System.Threading.Tasks.Task LoadAsync(System.IO.Stream input, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, string format = null, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null, System.Threading.CancellationToken token = default) + public static System.Threading.Tasks.Task LoadAsync(System.IO.Stream input, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, string? format = null, Microsoft.OpenApi.Reader.OpenApiReaderSettings? settings = null, System.Threading.CancellationToken token = default) where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { } - public static Microsoft.OpenApi.Reader.ReadResult Parse(string input, string format = null, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null) { } - public static T Parse(string input, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, out Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnostic, string format = null, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null) + public static Microsoft.OpenApi.Reader.ReadResult Parse(string input, string? format = null, Microsoft.OpenApi.Reader.OpenApiReaderSettings? settings = null) { } + public static T? Parse(string input, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, out Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnostic, string? format = null, Microsoft.OpenApi.Reader.OpenApiReaderSettings? settings = null) where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { } } public class OpenApiReaderSettings { public OpenApiReaderSettings() { } - public System.Uri BaseUrl { get; set; } - public Microsoft.OpenApi.Interfaces.IStreamLoader CustomExternalLoader { get; set; } - public System.Collections.Generic.List DefaultContentType { get; set; } - public System.Collections.Generic.Dictionary> ExtensionParsers { get; set; } + public System.Uri? BaseUrl { get; set; } + public Microsoft.OpenApi.Interfaces.IStreamLoader? CustomExternalLoader { get; set; } + public System.Collections.Generic.List? DefaultContentType { get; set; } + public System.Collections.Generic.Dictionary>? ExtensionParsers { get; set; } public System.Net.Http.HttpClient HttpClient { init; } public bool LeaveStreamOpen { get; set; } public bool LoadExternalRefs { get; set; } @@ -1493,34 +1492,34 @@ namespace Microsoft.OpenApi.Reader public class ParsingContext { public ParsingContext(Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnostic) { } - public System.Uri BaseUrl { get; set; } - public System.Collections.Generic.List DefaultContentType { get; set; } + public System.Uri? BaseUrl { get; set; } + public System.Collections.Generic.List? DefaultContentType { get; set; } public Microsoft.OpenApi.Reader.OpenApiDiagnostic Diagnostic { get; } - public System.Collections.Generic.Dictionary> ExtensionParsers { get; set; } + public System.Collections.Generic.Dictionary>? ExtensionParsers { get; set; } public void EndObject() { } - public T GetFromTempStorage(string key, object scope = null) { } + public T? GetFromTempStorage(string key, object? scope = null) { } public string GetLocation() { } public Microsoft.OpenApi.Models.OpenApiDocument Parse(System.Text.Json.Nodes.JsonNode jsonNode) { } - public T ParseFragment(System.Text.Json.Nodes.JsonNode jsonNode, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument) + public T? ParseFragment(System.Text.Json.Nodes.JsonNode jsonNode, Microsoft.OpenApi.OpenApiSpecVersion version, Microsoft.OpenApi.Models.OpenApiDocument openApiDocument) where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { } public void PopLoop(string loopid) { } public bool PushLoop(string loopId, string key) { } - public void SetTempStorage(string key, object value, object scope = null) { } + public void SetTempStorage(string key, object? value, object? scope = null) { } public void StartObject(string objectName) { } } public class ReadResult { public ReadResult() { } - public Microsoft.OpenApi.Reader.OpenApiDiagnostic Diagnostic { get; set; } - public Microsoft.OpenApi.Models.OpenApiDocument Document { get; set; } - public void Deconstruct(out Microsoft.OpenApi.Models.OpenApiDocument document, out Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnostic) { } + public Microsoft.OpenApi.Reader.OpenApiDiagnostic? Diagnostic { get; set; } + public Microsoft.OpenApi.Models.OpenApiDocument? Document { get; set; } + public void Deconstruct(out Microsoft.OpenApi.Models.OpenApiDocument? document, out Microsoft.OpenApi.Reader.OpenApiDiagnostic? diagnostic) { } } } namespace Microsoft.OpenApi.Reader.ParseNodes { public static class JsonPointerExtensions { - public static System.Text.Json.Nodes.JsonNode Find(this Microsoft.OpenApi.JsonPointer currentPointer, System.Text.Json.Nodes.JsonNode baseJsonNode) { } + public static System.Text.Json.Nodes.JsonNode? Find(this Microsoft.OpenApi.JsonPointer currentPointer, System.Text.Json.Nodes.JsonNode baseJsonNode) { } } } namespace Microsoft.OpenApi.Reader.Services @@ -1536,17 +1535,17 @@ namespace Microsoft.OpenApi.Services public class CurrentKeys { public CurrentKeys() { } - public string Callback { get; set; } - public string Content { get; set; } - public string Encoding { get; } - public string Example { get; } - public string Extension { get; } - public string Header { get; } - public string Link { get; set; } - public System.Net.Http.HttpMethod Operation { get; set; } - public string Path { get; set; } - public string Response { get; set; } - public string ServerVariable { get; } + public string? Callback { get; set; } + public string? Content { get; set; } + public string? Encoding { get; } + public string? Example { get; } + public string? Extension { get; } + public string? Header { get; } + public string? Link { get; set; } + public System.Net.Http.HttpMethod? Operation { get; set; } + public string? Path { get; set; } + public string? Response { get; set; } + public string? ServerVariable { get; } } public enum MermaidNodeShape { @@ -1565,11 +1564,11 @@ namespace Microsoft.OpenApi.Services { public static Microsoft.OpenApi.Models.OpenApiDocument CreateFilteredDocument(Microsoft.OpenApi.Models.OpenApiDocument source, System.Func predicate) { } public static Microsoft.OpenApi.Services.OpenApiUrlTreeNode CreateOpenApiUrlTreeNode(System.Collections.Generic.Dictionary sources) { } - public static System.Func CreatePredicate(string operationIds = null, string tags = null, System.Collections.Generic.Dictionary> requestUrls = null, Microsoft.OpenApi.Models.OpenApiDocument source = null) { } + public static System.Func CreatePredicate(string? operationIds = null, string? tags = null, System.Collections.Generic.Dictionary>? requestUrls = null, Microsoft.OpenApi.Models.OpenApiDocument? source = null) { } } public class OpenApiReferenceError : Microsoft.OpenApi.Models.OpenApiError { - public readonly Microsoft.OpenApi.Models.OpenApiReference Reference; + public readonly Microsoft.OpenApi.Models.OpenApiReference? Reference; public OpenApiReferenceError(Microsoft.OpenApi.Exceptions.OpenApiException exception) { } public OpenApiReferenceError(Microsoft.OpenApi.Models.OpenApiReference reference, string message) { } } @@ -1647,18 +1646,18 @@ namespace Microsoft.OpenApi.Services public class OpenApiWalker { public OpenApiWalker(Microsoft.OpenApi.Services.OpenApiVisitorBase visitor) { } - public void Walk(Microsoft.OpenApi.Models.OpenApiDocument doc) { } + public void Walk(Microsoft.OpenApi.Models.OpenApiDocument? doc) { } } public class OpenApiWorkspace { public OpenApiWorkspace() { } public OpenApiWorkspace(Microsoft.OpenApi.Services.OpenApiWorkspace workspace) { } public OpenApiWorkspace(System.Uri baseUrl) { } - public System.Uri BaseUrl { get; } - public void AddDocumentId(string key, System.Uri value) { } + public System.Uri? BaseUrl { get; } + public void AddDocumentId(string? key, System.Uri? value) { } public int ComponentsCount() { } public bool Contains(string location) { } - public System.Uri GetDocumentId(string key) { } + public System.Uri? GetDocumentId(string? key) { } public bool RegisterComponentForDocument(Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, T componentToRegister, string id) { } public void RegisterComponents(Microsoft.OpenApi.Models.OpenApiDocument document) { } public T? ResolveReference(string location) { } @@ -1673,16 +1672,15 @@ namespace Microsoft.OpenApi.Services public class SearchResult { public SearchResult() { } - public Microsoft.OpenApi.Services.CurrentKeys CurrentKeys { get; set; } - public Microsoft.OpenApi.Models.OpenApiOperation Operation { get; set; } - public System.Collections.Generic.IList Parameters { get; set; } + public Microsoft.OpenApi.Services.CurrentKeys? CurrentKeys { get; set; } + public Microsoft.OpenApi.Models.OpenApiOperation? Operation { get; set; } + public System.Collections.Generic.IList? Parameters { get; set; } } } namespace Microsoft.OpenApi.Validations { public interface IValidationContext { - Microsoft.OpenApi.Models.OpenApiDocument HostDocument { get; } string PathString { get; } void AddError(Microsoft.OpenApi.Validations.OpenApiValidatorError error); void AddWarning(Microsoft.OpenApi.Validations.OpenApiValidatorWarning warning); @@ -1691,9 +1689,8 @@ namespace Microsoft.OpenApi.Validations } public class OpenApiValidator : Microsoft.OpenApi.Services.OpenApiVisitorBase, Microsoft.OpenApi.Validations.IValidationContext { - public OpenApiValidator(Microsoft.OpenApi.Validations.ValidationRuleSet ruleSet, Microsoft.OpenApi.Models.OpenApiDocument hostDocument = null) { } + public OpenApiValidator(Microsoft.OpenApi.Validations.ValidationRuleSet ruleSet) { } public System.Collections.Generic.IEnumerable Errors { get; } - public Microsoft.OpenApi.Models.OpenApiDocument HostDocument { get; set; } public System.Collections.Generic.IEnumerable Warnings { get; } public void AddError(Microsoft.OpenApi.Validations.OpenApiValidatorError error) { } public void AddWarning(Microsoft.OpenApi.Validations.OpenApiValidatorWarning warning) { } @@ -1772,7 +1769,7 @@ namespace Microsoft.OpenApi.Validations public bool Remove(System.Type key) { } public void Remove(string ruleName) { } public bool Remove(System.Type key, Microsoft.OpenApi.Validations.ValidationRule rule) { } - public bool TryGetValue(System.Type key, out System.Collections.Generic.IList rules) { } + public bool TryGetValue(System.Type key, out System.Collections.Generic.IList? rules) { } public bool Update(System.Type key, Microsoft.OpenApi.Validations.ValidationRule newRule, Microsoft.OpenApi.Validations.ValidationRule oldRule) { } public static void AddValidationRules(Microsoft.OpenApi.Validations.ValidationRuleSet ruleSet, System.Collections.Generic.IDictionary> rules) { } public static Microsoft.OpenApi.Validations.ValidationRuleSet GetDefaultRuleSet() { } @@ -1865,8 +1862,8 @@ namespace Microsoft.OpenApi.Validations.Rules public static class OpenApiSchemaRules { public static Microsoft.OpenApi.Validations.ValidationRule ValidateSchemaDiscriminator { get; } - public static bool TraverseSchemaElements(string discriminatorName, System.Collections.Generic.IList childSchema) { } - public static bool ValidateChildSchemaAgainstDiscriminator(Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema schema, string discriminatorName) { } + public static bool TraverseSchemaElements(string discriminatorName, System.Collections.Generic.IList? childSchema) { } + public static bool ValidateChildSchemaAgainstDiscriminator(Microsoft.OpenApi.Models.Interfaces.IOpenApiSchema schema, string? discriminatorName) { } } [Microsoft.OpenApi.Validations.Rules.OpenApiRule] public static class OpenApiServerRules @@ -1906,7 +1903,7 @@ namespace Microsoft.OpenApi.Writers { public OpenApiJsonWriter(System.IO.TextWriter textWriter) { } public OpenApiJsonWriter(System.IO.TextWriter textWriter, Microsoft.OpenApi.Writers.OpenApiJsonWriterSettings settings) { } - public OpenApiJsonWriter(System.IO.TextWriter textWriter, Microsoft.OpenApi.Writers.OpenApiWriterSettings settings, bool terseOutput = false) { } + public OpenApiJsonWriter(System.IO.TextWriter textWriter, Microsoft.OpenApi.Writers.OpenApiWriterSettings? settings, bool terseOutput = false) { } protected override int BaseIndentation { get; } public override void WriteEndArray() { } public override void WriteEndObject() { } @@ -1926,19 +1923,19 @@ namespace Microsoft.OpenApi.Writers } public static class OpenApiWriterAnyExtensions { - public static void WriteAny(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, System.Text.Json.Nodes.JsonNode node) { } - public static void WriteExtensions(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, System.Collections.Generic.IDictionary extensions, Microsoft.OpenApi.OpenApiSpecVersion specVersion) { } + public static void WriteAny(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, System.Text.Json.Nodes.JsonNode? node) { } + public static void WriteExtensions(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, System.Collections.Generic.IDictionary? extensions, Microsoft.OpenApi.OpenApiSpecVersion specVersion) { } } public abstract class OpenApiWriterBase : Microsoft.OpenApi.Writers.IOpenApiWriter { protected const string IndentationString = " "; protected readonly System.Collections.Generic.Stack Scopes; protected OpenApiWriterBase(System.IO.TextWriter textWriter) { } - protected OpenApiWriterBase(System.IO.TextWriter textWriter, Microsoft.OpenApi.Writers.OpenApiWriterSettings settings) { } + protected OpenApiWriterBase(System.IO.TextWriter textWriter, Microsoft.OpenApi.Writers.OpenApiWriterSettings? settings) { } protected abstract int BaseIndentation { get; } public Microsoft.OpenApi.Writers.OpenApiWriterSettings Settings { get; set; } protected System.IO.TextWriter Writer { get; } - protected Microsoft.OpenApi.Writers.Scope CurrentScope() { } + protected Microsoft.OpenApi.Writers.Scope? CurrentScope() { } public virtual void DecreaseIndentation() { } protected Microsoft.OpenApi.Writers.Scope EndScope(Microsoft.OpenApi.Writers.ScopeType type) { } public System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken = default) { } @@ -1957,7 +1954,6 @@ namespace Microsoft.OpenApi.Writers public abstract void WriteRaw(string value); public abstract void WriteStartArray(); public abstract void WriteStartObject(); - public void WriteV2Examples(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Microsoft.OpenApi.Models.OpenApiExample example, Microsoft.OpenApi.OpenApiSpecVersion version) { } public virtual void WriteValue(System.DateTime value) { } public virtual void WriteValue(System.DateTimeOffset value) { } public virtual void WriteValue(bool value) { } @@ -1966,24 +1962,25 @@ namespace Microsoft.OpenApi.Writers public virtual void WriteValue(float value) { } public virtual void WriteValue(int value) { } public virtual void WriteValue(long value) { } - public virtual void WriteValue(object value) { } + public virtual void WriteValue(object? value) { } public abstract void WriteValue(string value); protected abstract void WriteValueSeparator(); + public static void WriteV2Examples(Microsoft.OpenApi.Writers.IOpenApiWriter writer, Microsoft.OpenApi.Models.OpenApiExample example, Microsoft.OpenApi.OpenApiSpecVersion version) { } } public static class OpenApiWriterExtensions { - public static void WriteOptionalCollection(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IEnumerable elements, System.Action action) { } - public static void WriteOptionalCollection(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IEnumerable elements, System.Action action) { } - public static void WriteOptionalMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary> elements, System.Action> action) { } - public static void WriteOptionalMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary elements, System.Action action) { } - public static void WriteOptionalMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary elements, System.Action action) { } - public static void WriteOptionalMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary elements, System.Action action) { } - public static void WriteOptionalMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary elements, System.Action action) + public static void WriteOptionalCollection(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IEnumerable? elements, System.Action action) { } + public static void WriteOptionalCollection(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IEnumerable? elements, System.Action action) { } + public static void WriteOptionalMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary>? elements, System.Action> action) { } + public static void WriteOptionalMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary? elements, System.Action action) { } + public static void WriteOptionalMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary? elements, System.Action action) { } + public static void WriteOptionalMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary? elements, System.Action action) { } + public static void WriteOptionalMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary? elements, System.Action action) where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { } - public static void WriteOptionalMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary elements, System.Action action) + public static void WriteOptionalMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary? elements, System.Action action) where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { } public static void WriteOptionalObject(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, T? value, System.Action action) { } - public static void WriteProperty(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, string value) { } + public static void WriteProperty(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, string? value) { } public static void WriteProperty(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, bool value, bool defaultValue = false) { } public static void WriteProperty(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, bool? value, bool defaultValue = false) { } public static void WriteProperty(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, T value) @@ -1992,11 +1989,11 @@ namespace Microsoft.OpenApi.Writers where T : struct { } public static void WriteRequiredCollection(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IEnumerable elements, System.Action action) where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { } - public static void WriteRequiredMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary elements, System.Action action) { } - public static void WriteRequiredMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary elements, System.Action action) + public static void WriteRequiredMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary? elements, System.Action action) { } + public static void WriteRequiredMap(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, System.Collections.Generic.IDictionary? elements, System.Action action) where T : Microsoft.OpenApi.Interfaces.IOpenApiElement { } public static void WriteRequiredObject(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, T? value, System.Action action) { } - public static void WriteRequiredProperty(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, string value) { } + public static void WriteRequiredProperty(this Microsoft.OpenApi.Writers.IOpenApiWriter writer, string name, string? value) { } } public class OpenApiWriterSettings { @@ -2007,7 +2004,7 @@ namespace Microsoft.OpenApi.Writers public class OpenApiYamlWriter : Microsoft.OpenApi.Writers.OpenApiWriterBase { public OpenApiYamlWriter(System.IO.TextWriter textWriter) { } - public OpenApiYamlWriter(System.IO.TextWriter textWriter, Microsoft.OpenApi.Writers.OpenApiWriterSettings settings) { } + public OpenApiYamlWriter(System.IO.TextWriter textWriter, Microsoft.OpenApi.Writers.OpenApiWriterSettings? settings) { } protected override int BaseIndentation { get; } public bool UseLiteralStyle { get; set; } public override void WriteEndArray() { } diff --git a/test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs b/test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs index feee331af..6af474e22 100644 --- a/test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs @@ -58,8 +58,7 @@ public void LocateTopLevelArrayItems() "#/servers/0", "#/servers/1", "#/paths", - "#/tags", - "#/tags/0" + "#/tags" }, locator.Locations); }