diff --git a/src/Microsoft.OpenApi.Hidi/StatsVisitor.cs b/src/Microsoft.OpenApi.Hidi/StatsVisitor.cs index a6ea032f1..700918f4e 100644 --- a/src/Microsoft.OpenApi.Hidi/StatsVisitor.cs +++ b/src/Microsoft.OpenApi.Hidi/StatsVisitor.cs @@ -62,7 +62,7 @@ public override void Visit(OpenApiOperation operation) public int LinkCount { get; set; } - public override void Visit(OpenApiLink link) + public override void Visit(IOpenApiLink link) { LinkCount++; } diff --git a/src/Microsoft.OpenApi.Workbench/StatsVisitor.cs b/src/Microsoft.OpenApi.Workbench/StatsVisitor.cs index 3e3b1cf93..41d14fe1d 100644 --- a/src/Microsoft.OpenApi.Workbench/StatsVisitor.cs +++ b/src/Microsoft.OpenApi.Workbench/StatsVisitor.cs @@ -62,7 +62,7 @@ public override void Visit(OpenApiOperation operation) public int LinkCount { get; set; } - public override void Visit(OpenApiLink link) + public override void Visit(IOpenApiLink link) { LinkCount++; } diff --git a/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiLink.cs b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiLink.cs new file mode 100644 index 000000000..854c945f8 --- /dev/null +++ b/src/Microsoft.OpenApi/Models/Interfaces/IOpenApiLink.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using Microsoft.OpenApi.Interfaces; + +namespace Microsoft.OpenApi.Models.Interfaces; + +/// +/// Defines the base properties for the link object. +/// This interface is provided for type assertions but should not be implemented by package consumers beyond automatic mocking. +/// +public interface IOpenApiLink : IOpenApiDescribedElement, IOpenApiSerializable, IOpenApiReadOnlyExtensible +{ + /// + /// 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; } + + /// + /// 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; } + + /// + /// A map representing parameters to pass to an operation as specified with operationId or identified via operationRef. + /// + public IDictionary Parameters { get; } + + /// + /// A literal value or {expression} to use as a request body when calling the target operation. + /// + public RuntimeExpressionAnyWrapper RequestBody { get; } + /// + /// A server object to be used by the target operation. + /// + public OpenApiServer Server { get; } +} diff --git a/src/Microsoft.OpenApi/Models/OpenApiComponents.cs b/src/Microsoft.OpenApi/Models/OpenApiComponents.cs index c578ddc9a..b171cef5b 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiComponents.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiComponents.cs @@ -56,9 +56,9 @@ public class OpenApiComponents : IOpenApiSerializable, IOpenApiExtensible new Dictionary(); /// - /// An object to hold reusable Objects. + /// An object to hold reusable Objects. /// - public IDictionary? Links { get; set; } = new Dictionary(); + public IDictionary? Links { get; set; } = new Dictionary(); /// /// An object to hold reusable Objects. @@ -92,7 +92,7 @@ public OpenApiComponents(OpenApiComponents? components) RequestBodies = components?.RequestBodies != null ? new Dictionary(components.RequestBodies) : null; Headers = components?.Headers != null ? new Dictionary(components.Headers) : null; SecuritySchemes = components?.SecuritySchemes != null ? new Dictionary(components.SecuritySchemes) : null; - Links = components?.Links != null ? new Dictionary(components.Links) : null; + Links = components?.Links != null ? new Dictionary(components.Links) : null; Callbacks = components?.Callbacks != null ? new Dictionary(components.Callbacks) : null; PathItems = components?.PathItems != null ? new Dictionary(components.PathItems) : null; Extensions = components?.Extensions != null ? new Dictionary(components.Extensions) : null; diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index 6985aea1a..ae92bb60f 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -604,7 +604,7 @@ public bool AddComponent(string id, T componentToRegister) Components.RequestBodies.Add(id, openApiRequestBody); break; case OpenApiLink openApiLink: - Components.Links ??= new Dictionary(); + Components.Links ??= new Dictionary(); Components.Links.Add(id, openApiLink); break; case OpenApiCallback openApiCallback: diff --git a/src/Microsoft.OpenApi/Models/OpenApiLink.cs b/src/Microsoft.OpenApi/Models/OpenApiLink.cs index 715826c67..fec27dd67 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiLink.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiLink.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; +using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models @@ -11,55 +12,28 @@ namespace Microsoft.OpenApi.Models /// /// Link Object. /// - public class OpenApiLink : IOpenApiReferenceable, IOpenApiExtensible + public class OpenApiLink : IOpenApiReferenceable, IOpenApiExtensible, IOpenApiLink { - /// - /// 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 virtual string OperationRef { get; set; } + /// + public string OperationRef { get; set; } - /// - /// The name of an existing, resolvable OAS operation, as defined with a unique operationId. - /// This field is mutually exclusive of the operationRef field. - /// - public virtual string OperationId { get; set; } + /// + public string OperationId { get; set; } - /// - /// A map representing parameters to pass to an operation as specified with operationId or identified via operationRef. - /// - public virtual Dictionary Parameters { get; set; } = - new(); + /// + public IDictionary Parameters { get; set; } = new Dictionary(); - /// - /// A literal value or {expression} to use as a request body when calling the target operation. - /// - public virtual RuntimeExpressionAnyWrapper RequestBody { get; set; } - - /// - /// A description of the link. - /// - public virtual string Description { get; set; } - - /// - /// A server object to be used by the target operation. - /// - public virtual OpenApiServer Server { get; set; } + /// + public RuntimeExpressionAnyWrapper RequestBody { get; set; } - /// - /// This object MAY be extended with Specification Extensions. - /// - public virtual IDictionary Extensions { get; set; } = new Dictionary(); + /// + public string Description { get; set; } - /// - /// Indicates if object is populated with data or is just a reference to the data - /// - public virtual bool UnresolvedReference { get; set; } + /// + public OpenApiServer Server { get; set; } - /// - /// Reference pointer. - /// - public OpenApiReference Reference { get; set; } + /// + public IDictionary Extensions { get; set; } = new Dictionary(); /// /// Parameterless constructor @@ -69,36 +43,31 @@ public OpenApiLink() { } /// /// Initializes a copy of an object /// - public OpenApiLink(OpenApiLink link) + public OpenApiLink(IOpenApiLink link) { - OperationRef = link?.OperationRef ?? OperationRef; - OperationId = link?.OperationId ?? OperationId; - Parameters = link?.Parameters != null ? new(link?.Parameters) : null; - RequestBody = link?.RequestBody != null ? new(link?.RequestBody) : null; - Description = link?.Description ?? Description; - Server = link?.Server != null ? new(link?.Server) : null; - Extensions = link?.Extensions != null ? new Dictionary(link.Extensions) : null; - UnresolvedReference = link?.UnresolvedReference ?? UnresolvedReference; - Reference = link?.Reference != null ? new(link?.Reference) : null; + Utils.CheckArgumentNull(link); + OperationRef = link.OperationRef ?? OperationRef; + OperationId = link.OperationId ?? OperationId; + Parameters = link.Parameters != null ? new Dictionary(link.Parameters) : null; + RequestBody = link.RequestBody != null ? new(link.RequestBody) : null; + Description = link.Description ?? Description; + Server = link.Server != null ? new(link.Server) : null; + Extensions = link.Extensions != null ? new Dictionary(link.Extensions) : null; } - /// - /// Serialize to Open Api v3.1 - /// - public virtual void SerializeAsV31(IOpenApiWriter writer) + /// + public void SerializeAsV31(IOpenApiWriter writer) { SerializeInternal(writer, (writer, element) => element.SerializeAsV31(writer)); } - /// - /// Serialize to Open Api v3.0 - /// - public virtual void SerializeAsV3(IOpenApiWriter writer) + /// + public void SerializeAsV3(IOpenApiWriter writer) { SerializeInternal(writer, (writer, element) => element.SerializeAsV3(writer)); } - internal virtual void SerializeInternal(IOpenApiWriter writer, Action callback) + internal void SerializeInternal(IOpenApiWriter writer, Action callback) { Utils.CheckArgumentNull(writer); @@ -128,9 +97,7 @@ internal virtual void SerializeInternal(IOpenApiWriter writer, Action - /// Serialize to Open Api v2.0 - /// + /// public void SerializeAsV2(IOpenApiWriter writer) { // Link object does not exist in V2. diff --git a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs index 755af74cd..3896c6b76 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiResponse.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiResponse.cs @@ -36,7 +36,7 @@ public class OpenApiResponse : IOpenApiReferenceable, IOpenApiExtensible /// The key of the map is a short name for the link, /// following the naming constraints of the names for Component Objects. /// - public virtual IDictionary Links { get; set; } = new Dictionary(); + public virtual IDictionary Links { get; set; } = new Dictionary(); /// /// This object MAY be extended with Specification Extensions. @@ -66,7 +66,7 @@ public OpenApiResponse(OpenApiResponse response) Description = response?.Description ?? Description; Headers = response?.Headers != null ? new Dictionary(response.Headers) : null; Content = response?.Content != null ? new Dictionary(response.Content) : null; - Links = response?.Links != null ? new Dictionary(response.Links) : null; + Links = response?.Links != null ? new Dictionary(response.Links) : null; Extensions = response?.Extensions != null ? new Dictionary(response.Extensions) : null; UnresolvedReference = response?.UnresolvedReference ?? UnresolvedReference; Reference = response?.Reference != null ? new(response?.Reference) : null; diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs index b9d9758f1..f357c4532 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs @@ -69,8 +69,8 @@ public OpenApiCallbackReference(string referenceId, OpenApiDocument hostDocument public OpenApiCallbackReference(OpenApiCallbackReference callback) { Utils.CheckArgumentNull(callback); - Reference = callback?.Reference != null ? new(callback.Reference) : null; - UnresolvedReference = callback?.UnresolvedReference ?? false; + Reference = callback.Reference != null ? new(callback.Reference) : null; + UnresolvedReference = callback.UnresolvedReference; } internal OpenApiCallbackReference(OpenApiCallback target, string referenceId) diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs index 8d4eeabb1..9f1842001 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs @@ -67,8 +67,8 @@ public OpenApiExampleReference(string referenceId, OpenApiDocument hostDocument, public OpenApiExampleReference(OpenApiExampleReference example) { Utils.CheckArgumentNull(example); - Reference = example?.Reference != null ? new(example.Reference) : null; - UnresolvedReference = example?.UnresolvedReference ?? false; + Reference = example.Reference != null ? new(example.Reference) : null; + UnresolvedReference = example.UnresolvedReference; //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 } diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs index 614ab1446..57a4b1e4f 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; +using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models.References @@ -11,12 +12,14 @@ namespace Microsoft.OpenApi.Models.References /// /// Link Object Reference. /// - public class OpenApiLinkReference : OpenApiLink, IOpenApiReferenceHolder + public class OpenApiLinkReference : IOpenApiLink, IOpenApiReferenceHolder { - internal OpenApiLink _target; - private readonly OpenApiReference _reference; - private string _description; + /// + public OpenApiReference Reference { get; set; } + /// + public bool UnresolvedReference { get; set; } + internal OpenApiLink _target; /// /// Gets the target link. /// @@ -27,10 +30,8 @@ public OpenApiLink Target { get { - _target ??= Reference.HostDocument.ResolveReferenceTo(_reference); - OpenApiLink resolved = new OpenApiLink(_target); - if (!string.IsNullOrEmpty(_description)) resolved.Description = _description; - return resolved; + _target ??= Reference.HostDocument.ResolveReferenceTo(Reference); + return _target; } } @@ -48,22 +49,33 @@ public OpenApiLinkReference(string referenceId, OpenApiDocument hostDocument, st { Utils.CheckArgumentNullOrEmpty(referenceId); - _reference = new OpenApiReference() + Reference = new OpenApiReference() { Id = referenceId, HostDocument = hostDocument, Type = ReferenceType.Link, ExternalResource = externalResource }; + } + /// + /// Copy constructor. + /// + /// The reference to copy + public OpenApiLinkReference(OpenApiLinkReference reference) + { + Utils.CheckArgumentNull(reference); - Reference = _reference; + Reference = reference.Reference != null ? new(reference.Reference) : null; + UnresolvedReference = reference.UnresolvedReference; + //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 } internal OpenApiLinkReference(OpenApiLink target, string referenceId) { _target = target; - _reference = new OpenApiReference() + Reference = new OpenApiReference() { Id = referenceId, Type = ReferenceType.Link, @@ -71,63 +83,79 @@ internal OpenApiLinkReference(OpenApiLink target, string referenceId) } /// - public override string OperationRef { get => Target.OperationRef; set => Target.OperationRef = value; } + public string Description + { + get => string.IsNullOrEmpty(Reference?.Description) ? Target?.Description : Reference.Description; + set + { + if (Reference is not null) + { + Reference.Description = value; + } + } + } /// - public override string OperationId { get => Target.OperationId; set => Target.OperationId = value; } + public string OperationRef { get => Target?.OperationRef; } /// - public override OpenApiServer Server { get => Target.Server; set => Target.Server = value; } + public string OperationId { get => Target?.OperationId; } /// - public override string Description - { - get => string.IsNullOrEmpty(_description) ? Target.Description : _description; - set => _description = value; - } + public OpenApiServer Server { get => Target?.Server; } /// - public override Dictionary Parameters { get => Target.Parameters; set => Target.Parameters = value; } + public IDictionary Parameters { get => Target?.Parameters; } /// - public override RuntimeExpressionAnyWrapper RequestBody { get => Target.RequestBody; set => Target.RequestBody = value; } + public RuntimeExpressionAnyWrapper RequestBody { get => Target?.RequestBody; } /// - public override IDictionary Extensions { get => base.Extensions; set => base.Extensions = value; } + public IDictionary Extensions { get => Target?.Extensions; } /// - public override void SerializeAsV3(IOpenApiWriter writer) + public void SerializeAsV3(IOpenApiWriter writer) { - if (!writer.GetSettings().ShouldInlineReference(_reference)) + if (!writer.GetSettings().ShouldInlineReference(Reference)) { - _reference.SerializeAsV3(writer); - return; + Reference.SerializeAsV3(writer); } else { - SerializeInternal(writer, (writer, element) => element.SerializeAsV3(writer)); + SerializeInternal(writer, (writer, element) => CopyReferenceAsTargetElementWithOverrides(element).SerializeAsV3(writer)); } } /// - public override void SerializeAsV31(IOpenApiWriter writer) + public void SerializeAsV31(IOpenApiWriter writer) { - if (!writer.GetSettings().ShouldInlineReference(_reference)) + if (!writer.GetSettings().ShouldInlineReference(Reference)) { - _reference.SerializeAsV31(writer); - return; + Reference.SerializeAsV31(writer); } else { - SerializeInternal(writer, (writer, element) => element.SerializeAsV31(writer)); + SerializeInternal(writer, (writer, element) => CopyReferenceAsTargetElementWithOverrides(element).SerializeAsV31(writer)); } - } + } + + /// + public void SerializeAsV2(IOpenApiWriter writer) + { + // Link object does not exist in V2. + } + + /// + public IOpenApiLink CopyReferenceAsTargetElementWithOverrides(IOpenApiLink source) + { + return source is OpenApiLink ? new OpenApiLink(this) : source; + } /// private void SerializeInternal(IOpenApiWriter writer, - Action action) + Action action) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); action(writer, Target); } } diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs index 0f74e3ad5..57d8fba2b 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs @@ -86,9 +86,9 @@ public override string Description /// public override IDictionary Headers { get => _headers is not null ? _headers : Target?.Headers; set => _headers = value; } - private IDictionary _links; + private IDictionary _links; /// - public override IDictionary Links { get => _links is not null ? _links : Target?.Links; set => _links = value; } + public override IDictionary Links { get => _links is not null ? _links : Target?.Links; set => _links = value; } private IDictionary _extensions; /// diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiLinkDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiLinkDeserializer.cs index 049ecc8cc..9744ea256 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiLinkDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiLinkDeserializer.cs @@ -3,6 +3,7 @@ using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; @@ -44,7 +45,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, }; - public static OpenApiLink LoadLink(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiLink LoadLink(ParseNode node, OpenApiDocument hostDocument) { var mapNode = node.CheckMapNode("link"); var link = new OpenApiLink(); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiLinkDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiLinkDeserializer.cs index a849985fb..3924a41c7 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiLinkDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiLinkDeserializer.cs @@ -1,5 +1,6 @@ using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.Interfaces; using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; @@ -51,7 +52,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n, _) => o.AddExtension(p, LoadExtension(p,n))}, }; - public static OpenApiLink LoadLink(ParseNode node, OpenApiDocument hostDocument) + public static IOpenApiLink LoadLink(ParseNode node, OpenApiDocument hostDocument) { var mapNode = node.CheckMapNode("link"); var link = new OpenApiLink(); diff --git a/src/Microsoft.OpenApi/Services/CopyReferences.cs b/src/Microsoft.OpenApi/Services/CopyReferences.cs index 2575a6f77..3125d75cc 100644 --- a/src/Microsoft.OpenApi/Services/CopyReferences.cs +++ b/src/Microsoft.OpenApi/Services/CopyReferences.cs @@ -127,9 +127,9 @@ private void AddLinkToComponents(OpenApiLink link, string referenceId = null) { EnsureComponentsExist(); EnsureLinksExist(); - if (!Components.Links.ContainsKey(referenceId ?? link.Reference.Id)) + if (!Components.Links.ContainsKey(referenceId)) { - Components.Links.Add(referenceId ?? link.Reference.Id, link); + Components.Links.Add(referenceId, link); } } private void AddCallbackToComponents(OpenApiCallback callback, string referenceId = null) @@ -235,7 +235,7 @@ private void EnsureCallbacksExist() private void EnsureLinksExist() { - _target.Components.Links ??= new Dictionary(); + _target.Components.Links ??= new Dictionary(); } private void EnsureSecuritySchemesExist() diff --git a/src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs b/src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs index 30fe66774..62ecb4c5d 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs @@ -239,14 +239,14 @@ public virtual void Visit(OpenApiSchema schema) /// /// Visits the links. /// - public virtual void Visit(IDictionary links) + public virtual void Visit(IDictionary links) { } /// - /// Visits + /// Visits /// - public virtual void Visit(OpenApiLink link) + public virtual void Visit(IOpenApiLink link) { } diff --git a/src/Microsoft.OpenApi/Services/OpenApiWalker.cs b/src/Microsoft.OpenApi/Services/OpenApiWalker.cs index 3451a9690..c578a7653 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiWalker.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiWalker.cs @@ -1059,9 +1059,9 @@ internal void Walk(OpenApiOAuthFlow oAuthFlow) } /// - /// Visits dictionary of and child objects + /// Visits dictionary of and child objects /// - internal void Walk(IDictionary links) + internal void Walk(IDictionary links) { if (links == null) { @@ -1084,7 +1084,7 @@ internal void Walk(IDictionary links) /// /// Visits and child objects /// - internal void Walk(OpenApiLink link, bool isComponent = false) + internal void Walk(IOpenApiLink link, bool isComponent = false) { if (link == null) { @@ -1198,7 +1198,7 @@ internal void Walk(IOpenApiElement element) case OpenApiExternalDocs e: Walk(e); break; case OpenApiHeader e: Walk(e); break; case OpenApiLink e: Walk(e); break; - case IDictionary e: Walk(e); break; + case IDictionary e: Walk(e); break; case OpenApiMediaType e: Walk(e); break; case OpenApiOAuthFlows e: Walk(e); break; case OpenApiOAuthFlow e: Walk(e); break; diff --git a/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs b/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs index e93113536..594d87eaa 100644 --- a/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs +++ b/src/Microsoft.OpenApi/Validations/OpenApiValidator.cs @@ -147,7 +147,7 @@ public void AddWarning(OpenApiValidatorWarning warning) public override void Visit(OpenApiPaths paths) => Validate(paths); /// - public override void Visit(OpenApiLink link) => Validate(link); + public override void Visit(IOpenApiLink link) => Validate(link); /// public override void Visit(IOpenApiExample example) => Validate(example); @@ -165,7 +165,7 @@ public void AddWarning(OpenApiValidatorWarning warning) /// public override void Visit(IDictionary examples) => Validate(examples, examples.GetType()); /// - public override void Visit(IDictionary links) => Validate(links, links.GetType()); + public override void Visit(IDictionary links) => Validate(links, links.GetType()); /// public override void Visit(IDictionary serverVariables) => Validate(serverVariables, serverVariables.GetType()); /// diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiLinkTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiLinkTests.cs index e1a949348..e97fbb6b8 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiLinkTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiLinkTests.cs @@ -45,11 +45,6 @@ public class OpenApiLinkTests public static readonly OpenApiLinkReference LinkReference = new(ReferencedLink, "example1"); public static readonly OpenApiLink ReferencedLink = new() { - Reference = new() - { - Type = ReferenceType.Link, - Id = "example1", - }, OperationId = "operationId1", Parameters = { diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 3ae26aa75..e881f649d 100644 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -363,6 +363,14 @@ namespace Microsoft.OpenApi.Models.Interfaces Microsoft.OpenApi.Models.OpenApiSchema Schema { get; } Microsoft.OpenApi.Models.ParameterStyle? Style { get; } } + public interface IOpenApiLink : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, 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; } + } public interface IOpenApiSummarizedElement : Microsoft.OpenApi.Interfaces.IOpenApiElement { string Summary { get; set; } @@ -400,7 +408,7 @@ namespace Microsoft.OpenApi.Models public System.Collections.Generic.IDictionary? Examples { 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? Links { get; set; } public System.Collections.Generic.IDictionary? Parameters { get; set; } public System.Collections.Generic.IDictionary? PathItems { get; set; } public System.Collections.Generic.IDictionary? RequestBodies { get; set; } @@ -724,22 +732,20 @@ namespace Microsoft.OpenApi.Models public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } - public class OpenApiLink : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + 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.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiLink { public OpenApiLink() { } - public OpenApiLink(Microsoft.OpenApi.Models.OpenApiLink link) { } - public Microsoft.OpenApi.Models.OpenApiReference Reference { get; set; } - public virtual string Description { get; set; } - public virtual System.Collections.Generic.IDictionary Extensions { get; set; } - public virtual string OperationId { get; set; } - public virtual string OperationRef { get; set; } - public virtual System.Collections.Generic.Dictionary Parameters { get; set; } - public virtual Microsoft.OpenApi.Models.RuntimeExpressionAnyWrapper RequestBody { get; set; } - public virtual Microsoft.OpenApi.Models.OpenApiServer Server { get; set; } - public virtual bool UnresolvedReference { get; set; } + public OpenApiLink(Microsoft.OpenApi.Models.Interfaces.IOpenApiLink link) { } + 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 void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } - public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } - public virtual void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } public class OpenApiMediaType : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiSerializable { @@ -892,7 +898,7 @@ namespace Microsoft.OpenApi.Models public virtual string Description { get; set; } public virtual System.Collections.Generic.IDictionary Extensions { get; set; } public virtual System.Collections.Generic.IDictionary Headers { get; set; } - public virtual System.Collections.Generic.IDictionary Links { get; set; } + public virtual System.Collections.Generic.IDictionary Links { get; set; } public virtual void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1191,19 +1197,24 @@ namespace Microsoft.OpenApi.Models.References public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } - public class OpenApiLinkReference : Microsoft.OpenApi.Models.OpenApiLink, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + public class OpenApiLinkReference : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReadOnlyExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiSerializable, Microsoft.OpenApi.Models.Interfaces.IOpenApiDescribedElement, Microsoft.OpenApi.Models.Interfaces.IOpenApiLink { + public OpenApiLinkReference(Microsoft.OpenApi.Models.References.OpenApiLinkReference reference) { } public OpenApiLinkReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument, 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.OpenApiReference Reference { get; set; } + public Microsoft.OpenApi.Models.RuntimeExpressionAnyWrapper RequestBody { get; } + public Microsoft.OpenApi.Models.OpenApiServer Server { get; } public Microsoft.OpenApi.Models.OpenApiLink Target { get; } - public override string Description { get; set; } - public override System.Collections.Generic.IDictionary Extensions { get; set; } - public override string OperationId { get; set; } - public override string OperationRef { get; set; } - public override System.Collections.Generic.Dictionary Parameters { get; set; } - public override Microsoft.OpenApi.Models.RuntimeExpressionAnyWrapper RequestBody { get; set; } - public override Microsoft.OpenApi.Models.OpenApiServer Server { get; set; } - public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } - public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public bool UnresolvedReference { get; set; } + public Microsoft.OpenApi.Models.Interfaces.IOpenApiLink CopyReferenceAsTargetElementWithOverrides(Microsoft.OpenApi.Models.Interfaces.IOpenApiLink source) { } + public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } public class OpenApiParameterReference : Microsoft.OpenApi.Models.OpenApiParameter, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiReferenceHolder, Microsoft.OpenApi.Interfaces.IOpenApiSerializable { @@ -1258,7 +1269,7 @@ namespace Microsoft.OpenApi.Models.References public override string Description { get; set; } public override System.Collections.Generic.IDictionary Extensions { get; set; } public override System.Collections.Generic.IDictionary Headers { get; set; } - public override System.Collections.Generic.IDictionary Links { get; set; } + public override System.Collections.Generic.IDictionary Links { get; set; } public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1534,6 +1545,7 @@ namespace Microsoft.OpenApi.Services public virtual void Visit(Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback callback) { } public virtual void Visit(Microsoft.OpenApi.Models.Interfaces.IOpenApiExample example) { } public virtual void Visit(Microsoft.OpenApi.Models.Interfaces.IOpenApiHeader header) { } + public virtual void Visit(Microsoft.OpenApi.Models.Interfaces.IOpenApiLink link) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiComponents components) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiContact contact) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiDocument doc) { } @@ -1541,7 +1553,6 @@ namespace Microsoft.OpenApi.Services public virtual void Visit(Microsoft.OpenApi.Models.OpenApiExternalDocs externalDocs) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiInfo info) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiLicense license) { } - public virtual void Visit(Microsoft.OpenApi.Models.OpenApiLink link) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiMediaType mediaType) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiOAuthFlow openApiOAuthFlow) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiOperation operation) { } @@ -1562,8 +1573,8 @@ namespace Microsoft.OpenApi.Services public virtual void Visit(System.Collections.Generic.IDictionary callbacks) { } public virtual void Visit(System.Collections.Generic.IDictionary examples) { } public virtual void Visit(System.Collections.Generic.IDictionary headers) { } + public virtual void Visit(System.Collections.Generic.IDictionary links) { } public virtual void Visit(System.Collections.Generic.IDictionary encodings) { } - public virtual void Visit(System.Collections.Generic.IDictionary links) { } public virtual void Visit(System.Collections.Generic.IDictionary content) { } public virtual void Visit(System.Collections.Generic.IDictionary webhooks) { } public virtual void Visit(System.Collections.Generic.IDictionary serverVariables) { } @@ -1633,6 +1644,7 @@ namespace Microsoft.OpenApi.Validations public override void Visit(Microsoft.OpenApi.Models.Interfaces.IOpenApiCallback callback) { } public override void Visit(Microsoft.OpenApi.Models.Interfaces.IOpenApiExample example) { } public override void Visit(Microsoft.OpenApi.Models.Interfaces.IOpenApiHeader header) { } + public override void Visit(Microsoft.OpenApi.Models.Interfaces.IOpenApiLink link) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiComponents components) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiContact contact) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiDocument doc) { } @@ -1640,7 +1652,6 @@ namespace Microsoft.OpenApi.Validations public override void Visit(Microsoft.OpenApi.Models.OpenApiExternalDocs externalDocs) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiInfo info) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiLicense license) { } - public override void Visit(Microsoft.OpenApi.Models.OpenApiLink link) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiMediaType mediaType) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiOAuthFlow openApiOAuthFlow) { } public override void Visit(Microsoft.OpenApi.Models.OpenApiOperation operation) { } @@ -1660,8 +1671,8 @@ namespace Microsoft.OpenApi.Validations public override void Visit(System.Collections.Generic.IDictionary callbacks) { } public override void Visit(System.Collections.Generic.IDictionary examples) { } public override void Visit(System.Collections.Generic.IDictionary headers) { } + public override void Visit(System.Collections.Generic.IDictionary links) { } public override void Visit(System.Collections.Generic.IDictionary encodings) { } - public override void Visit(System.Collections.Generic.IDictionary links) { } public override void Visit(System.Collections.Generic.IDictionary content) { } public override void Visit(System.Collections.Generic.IDictionary serverVariables) { } public override void Visit(System.Collections.Generic.IList example) { } diff --git a/test/Microsoft.OpenApi.Tests/Visitors/InheritanceTests.cs b/test/Microsoft.OpenApi.Tests/Visitors/InheritanceTests.cs index c78e41f19..f2634be52 100644 --- a/test/Microsoft.OpenApi.Tests/Visitors/InheritanceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Visitors/InheritanceTests.cs @@ -44,8 +44,8 @@ public void ExpectedVirtualsInvolved() visitor.Visit(default(OpenApiComponents)); visitor.Visit(default(OpenApiExternalDocs)); visitor.Visit(default(OpenApiSchema)); - visitor.Visit(default(IDictionary)); - visitor.Visit(default(OpenApiLink)); + visitor.Visit(default(IDictionary)); + visitor.Visit(default(IOpenApiLink)); visitor.Visit(default(IOpenApiCallback)); visitor.Visit(default(OpenApiTag)); visitor.Visit(default(IOpenApiHeader)); @@ -238,13 +238,13 @@ public override void Visit(OpenApiSchema schema) base.Visit(schema); } - public override void Visit(IDictionary links) + public override void Visit(IDictionary links) { EncodeCall(); base.Visit(links); } - public override void Visit(OpenApiLink link) + public override void Visit(IOpenApiLink link) { EncodeCall(); base.Visit(link);