Skip to content

Commit 159138c

Browse files
authored
Creates derived reference objects for on-demand reference resolution (#1290)
* Add reference classes * Add serialization methods to reference classes * Modify access modifiers * Add header reference class * Use Target property instead of this * Make Reference property readonly; add constructors to get reference value * Add new constructor * Add reference tests * Add Tag reference tests * Update tests, method signatures and properties * Revert access modifiers * Update methods * Update tests * Update tests * Add externalResource parameter to constructors This is to help capture externally referenced resources * Add tests for external reference resolution * Add description field * Update teg reference serializer and tests * Update PublicApi * Fix broken tests * Add guard clause for potentially null Target value * Check for null or empty for strings * Use local field for getter and setter * Additional check for null or empty for string properties
1 parent 4212ce0 commit 159138c

File tree

123 files changed

+3460
-304
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+3460
-304
lines changed

src/Microsoft.OpenApi.Readers/ParseNodes/AnyListFieldMapParameter.cs

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

44
using System;
55
using System.Collections.Generic;
6-
using System.Text.Json.Nodes;
76
using Microsoft.OpenApi.Any;
87
using Microsoft.OpenApi.Models;
98

src/Microsoft.OpenApi/Models/OpenApiCallback.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using Microsoft.OpenApi.Expressions;
88
using Microsoft.OpenApi.Interfaces;
99
using Microsoft.OpenApi.Writers;
10-
using static Microsoft.OpenApi.Extensions.OpenApiSerializableExtensions;
1110

1211
namespace Microsoft.OpenApi.Models
1312
{
@@ -19,13 +18,13 @@ public class OpenApiCallback : IOpenApiSerializable, IOpenApiReferenceable, IOpe
1918
/// <summary>
2019
/// A Path Item Object used to define a callback request and expected responses.
2120
/// </summary>
22-
public Dictionary<RuntimeExpression, OpenApiPathItem> PathItems { get; set; }
21+
public virtual Dictionary<RuntimeExpression, OpenApiPathItem> PathItems { get; set; }
2322
= new Dictionary<RuntimeExpression, OpenApiPathItem>();
2423

2524
/// <summary>
2625
/// Indicates if object is populated with data or is just a reference to the data
2726
/// </summary>
28-
public bool UnresolvedReference { get; set; }
27+
public virtual bool UnresolvedReference { get; set; }
2928

3029
/// <summary>
3130
/// Reference pointer.
@@ -35,7 +34,7 @@ public class OpenApiCallback : IOpenApiSerializable, IOpenApiReferenceable, IOpe
3534
/// <summary>
3635
/// This object MAY be extended with Specification Extensions.
3736
/// </summary>
38-
public IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
37+
public virtual IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
3938

4039
/// <summary>
4140
/// Parameter-less constructor
@@ -83,7 +82,7 @@ public void AddPathItem(RuntimeExpression expression, OpenApiPathItem pathItem)
8382
/// </summary>
8483
/// <param name="writer"></param>
8584
/// <exception cref="System.NotImplementedException"></exception>
86-
public void SerializeAsV31(IOpenApiWriter writer)
85+
public virtual void SerializeAsV31(IOpenApiWriter writer)
8786
{
8887
SerializeInternal(writer, (writer, element) => element.SerializeAsV31(writer),
8988
(writer, referenceElement) => referenceElement.SerializeAsV31WithoutReference(writer));
@@ -92,7 +91,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
9291
/// <summary>
9392
/// Serialize <see cref="OpenApiCallback"/> to Open Api v3.0
9493
/// </summary>
95-
public void SerializeAsV3(IOpenApiWriter writer)
94+
public virtual void SerializeAsV3(IOpenApiWriter writer)
9695
{
9796
SerializeInternal(writer, (writer, element) => element.SerializeAsV3(writer),
9897
(writer, referenceElement) => referenceElement.SerializeAsV3WithoutReference(writer));
@@ -111,7 +110,7 @@ private void SerializeInternal(IOpenApiWriter writer,
111110
writer = writer ?? throw Error.ArgumentNull(nameof(writer));
112111

113112
var target = this;
114-
113+
115114
if (Reference != null)
116115
{
117116
if (!writer.GetSettings().ShouldInlineReference(Reference))
@@ -124,6 +123,7 @@ private void SerializeInternal(IOpenApiWriter writer,
124123
target = GetEffective(Reference.HostDocument);
125124
}
126125
}
126+
127127
action(writer, target);
128128
}
129129

@@ -134,9 +134,9 @@ private void SerializeInternal(IOpenApiWriter writer,
134134
/// <returns>OpenApiCallback</returns>
135135
public OpenApiCallback GetEffective(OpenApiDocument doc)
136136
{
137-
if (this.Reference != null)
137+
if (Reference != null)
138138
{
139-
return doc.ResolveReferenceTo<OpenApiCallback>(this.Reference);
139+
return doc.ResolveReferenceTo<OpenApiCallback>(Reference);
140140
}
141141
else
142142
{
@@ -147,7 +147,7 @@ public OpenApiCallback GetEffective(OpenApiDocument doc)
147147
/// <summary>
148148
/// Serialize to OpenAPI V31 document without using reference.
149149
/// </summary>
150-
public void SerializeAsV31WithoutReference(IOpenApiWriter writer)
150+
public virtual void SerializeAsV31WithoutReference(IOpenApiWriter writer)
151151
{
152152
SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_1,
153153
(writer, element) => element.SerializeAsV31(writer));
@@ -156,13 +156,13 @@ public void SerializeAsV31WithoutReference(IOpenApiWriter writer)
156156
/// <summary>
157157
/// Serialize to OpenAPI V3 document without using reference.
158158
/// </summary>
159-
public void SerializeAsV3WithoutReference(IOpenApiWriter writer)
159+
public virtual void SerializeAsV3WithoutReference(IOpenApiWriter writer)
160160
{
161161
SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_0,
162162
(writer, element) => element.SerializeAsV3(writer));
163163
}
164-
165-
private void SerializeInternalWithoutReference(IOpenApiWriter writer, OpenApiSpecVersion version,
164+
165+
internal void SerializeInternalWithoutReference(IOpenApiWriter writer, OpenApiSpecVersion version,
166166
Action<IOpenApiWriter, IOpenApiSerializable> callback)
167167
{
168168
writer.WriteStartObject();

src/Microsoft.OpenApi/Models/OpenApiComponents.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,60 +16,60 @@ public class OpenApiComponents : IOpenApiSerializable, IOpenApiExtensible
1616
/// <summary>
1717
/// An object to hold reusable <see cref="OpenApiSchema"/> Objects.
1818
/// </summary>
19-
public IDictionary<string, OpenApiSchema> Schemas { get; set; } = new Dictionary<string, OpenApiSchema>();
19+
public virtual IDictionary<string, OpenApiSchema> Schemas { get; set; } = new Dictionary<string, OpenApiSchema>();
2020

2121
/// <summary>
2222
/// An object to hold reusable <see cref="OpenApiResponse"/> Objects.
2323
/// </summary>
24-
public IDictionary<string, OpenApiResponse> Responses { get; set; } = new Dictionary<string, OpenApiResponse>();
24+
public virtual IDictionary<string, OpenApiResponse> Responses { get; set; } = new Dictionary<string, OpenApiResponse>();
2525

2626
/// <summary>
2727
/// An object to hold reusable <see cref="OpenApiParameter"/> Objects.
2828
/// </summary>
29-
public IDictionary<string, OpenApiParameter> Parameters { get; set; } =
29+
public virtual IDictionary<string, OpenApiParameter> Parameters { get; set; } =
3030
new Dictionary<string, OpenApiParameter>();
3131

3232
/// <summary>
3333
/// An object to hold reusable <see cref="OpenApiExample"/> Objects.
3434
/// </summary>
35-
public IDictionary<string, OpenApiExample> Examples { get; set; } = new Dictionary<string, OpenApiExample>();
35+
public virtual IDictionary<string, OpenApiExample> Examples { get; set; } = new Dictionary<string, OpenApiExample>();
3636

3737
/// <summary>
3838
/// An object to hold reusable <see cref="OpenApiRequestBody"/> Objects.
3939
/// </summary>
40-
public IDictionary<string, OpenApiRequestBody> RequestBodies { get; set; } =
40+
public virtual IDictionary<string, OpenApiRequestBody> RequestBodies { get; set; } =
4141
new Dictionary<string, OpenApiRequestBody>();
4242

4343
/// <summary>
4444
/// An object to hold reusable <see cref="OpenApiHeader"/> Objects.
4545
/// </summary>
46-
public IDictionary<string, OpenApiHeader> Headers { get; set; } = new Dictionary<string, OpenApiHeader>();
46+
public virtual IDictionary<string, OpenApiHeader> Headers { get; set; } = new Dictionary<string, OpenApiHeader>();
4747

4848
/// <summary>
4949
/// An object to hold reusable <see cref="OpenApiSecurityScheme"/> Objects.
5050
/// </summary>
51-
public IDictionary<string, OpenApiSecurityScheme> SecuritySchemes { get; set; } =
51+
public virtual IDictionary<string, OpenApiSecurityScheme> SecuritySchemes { get; set; } =
5252
new Dictionary<string, OpenApiSecurityScheme>();
5353

5454
/// <summary>
5555
/// An object to hold reusable <see cref="OpenApiLink"/> Objects.
5656
/// </summary>
57-
public IDictionary<string, OpenApiLink> Links { get; set; } = new Dictionary<string, OpenApiLink>();
57+
public virtual IDictionary<string, OpenApiLink> Links { get; set; } = new Dictionary<string, OpenApiLink>();
5858

5959
/// <summary>
6060
/// An object to hold reusable <see cref="OpenApiCallback"/> Objects.
6161
/// </summary>
62-
public IDictionary<string, OpenApiCallback> Callbacks { get; set; } = new Dictionary<string, OpenApiCallback>();
62+
public virtual IDictionary<string, OpenApiCallback> Callbacks { get; set; } = new Dictionary<string, OpenApiCallback>();
6363

6464
/// <summary>
6565
/// An object to hold reusable <see cref="OpenApiPathItem"/> Object.
6666
/// </summary>
67-
public IDictionary<string, OpenApiPathItem> PathItems { get; set; } = new Dictionary<string, OpenApiPathItem>();
67+
public virtual IDictionary<string, OpenApiPathItem> PathItems { get; set; } = new Dictionary<string, OpenApiPathItem>();
6868

6969
/// <summary>
7070
/// This object MAY be extended with Specification Extensions.
7171
/// </summary>
72-
public IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
72+
public virtual IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
7373

7474
/// <summary>
7575
/// Parameter-less constructor

src/Microsoft.OpenApi/Models/OpenApiContact.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

44
using System;

src/Microsoft.OpenApi/Models/OpenApiDocument.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
using Microsoft.OpenApi.Interfaces;
1313
using Microsoft.OpenApi.Services;
1414
using Microsoft.OpenApi.Writers;
15-
using static Microsoft.OpenApi.Extensions.OpenApiSerializableExtensions;
1615

1716
namespace Microsoft.OpenApi.Models
1817
{

src/Microsoft.OpenApi/Models/OpenApiExample.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,43 +18,43 @@ public class OpenApiExample : IOpenApiSerializable, IOpenApiReferenceable, IOpen
1818
/// <summary>
1919
/// Short description for the example.
2020
/// </summary>
21-
public string Summary { get; set; }
21+
public virtual string Summary { get; set; }
2222

2323
/// <summary>
2424
/// Long description for the example.
2525
/// CommonMark syntax MAY be used for rich text representation.
2626
/// </summary>
27-
public string Description { get; set; }
27+
public virtual string Description { get; set; }
2828

2929
/// <summary>
3030
/// Embedded literal example. The value field and externalValue field are mutually
3131
/// exclusive. To represent examples of media types that cannot naturally represented
3232
/// in JSON or YAML, use a string value to contain the example, escaping where necessary.
3333
/// </summary>
34-
public OpenApiAny Value { get; set; }
34+
public virtual OpenApiAny Value { get; set; }
3535

3636
/// <summary>
3737
/// A URL that points to the literal example.
3838
/// This provides the capability to reference examples that cannot easily be
3939
/// included in JSON or YAML documents.
4040
/// The value field and externalValue field are mutually exclusive.
4141
/// </summary>
42-
public string ExternalValue { get; set; }
42+
public virtual string ExternalValue { get; set; }
4343

4444
/// <summary>
4545
/// This object MAY be extended with Specification Extensions.
4646
/// </summary>
47-
public IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
47+
public virtual IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();
4848

4949
/// <summary>
5050
/// Reference object.
5151
/// </summary>
52-
public OpenApiReference Reference { get; set; }
52+
public virtual OpenApiReference Reference { get; set; }
5353

5454
/// <summary>
5555
/// Indicates object is a placeholder reference to an actual object and does not contain valid data.
5656
/// </summary>
57-
public bool UnresolvedReference { get; set; } = false;
57+
public virtual bool UnresolvedReference { get; set; } = false;
5858

5959
/// <summary>
6060
/// Parameter-less constructor
@@ -79,7 +79,7 @@ public OpenApiExample(OpenApiExample example)
7979
/// Serialize <see cref="OpenApiExample"/> to Open Api v3.1
8080
/// </summary>
8181
/// <param name="writer"></param>
82-
public void SerializeAsV31(IOpenApiWriter writer)
82+
public virtual void SerializeAsV31(IOpenApiWriter writer)
8383
{
8484
SerializeInternal(writer, (writer, element) => element.SerializeAsV31(writer),
8585
(writer, element) => element.SerializeAsV31WithoutReference(writer));
@@ -89,13 +89,13 @@ public void SerializeAsV31(IOpenApiWriter writer)
8989
/// Serialize <see cref="OpenApiExample"/> to Open Api v3.0
9090
/// </summary>
9191
/// <param name="writer"></param>
92-
public void SerializeAsV3(IOpenApiWriter writer)
92+
public virtual void SerializeAsV3(IOpenApiWriter writer)
9393
{
9494
SerializeInternal(writer, (writer, element) => element.SerializeAsV3(writer),
9595
(writer, element) => element.SerializeAsV3WithoutReference(writer));
9696
}
9797

98-
private void SerializeInternal(IOpenApiWriter writer, Action<IOpenApiWriter, IOpenApiSerializable> callback,
98+
internal virtual void SerializeInternal(IOpenApiWriter writer, Action<IOpenApiWriter, IOpenApiSerializable> callback,
9999
Action<IOpenApiWriter, IOpenApiReferenceable> action)
100100
{
101101
writer = writer ?? throw Error.ArgumentNull(nameof(writer));
@@ -124,7 +124,7 @@ private void SerializeInternal(IOpenApiWriter writer, Action<IOpenApiWriter, IOp
124124
/// <returns>OpenApiExample</returns>
125125
public OpenApiExample GetEffective(OpenApiDocument doc)
126126
{
127-
if (this.Reference != null)
127+
if (Reference != null)
128128
{
129129
return doc.ResolveReferenceTo<OpenApiExample>(this.Reference);
130130
}
@@ -137,20 +137,20 @@ public OpenApiExample GetEffective(OpenApiDocument doc)
137137
/// <summary>
138138
/// Serialize to OpenAPI V31 example without using reference.
139139
/// </summary>
140-
public void SerializeAsV31WithoutReference(IOpenApiWriter writer)
140+
public virtual void SerializeAsV31WithoutReference(IOpenApiWriter writer)
141141
{
142142
SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_1);
143143
}
144144

145145
/// <summary>
146146
/// Serialize to OpenAPI V3 example without using reference.
147147
/// </summary>
148-
public void SerializeAsV3WithoutReference(IOpenApiWriter writer)
148+
public virtual void SerializeAsV3WithoutReference(IOpenApiWriter writer)
149149
{
150150
SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_0);
151151
}
152152

153-
private void SerializeInternalWithoutReference(IOpenApiWriter writer, OpenApiSpecVersion version)
153+
internal void SerializeInternalWithoutReference(IOpenApiWriter writer, OpenApiSpecVersion version)
154154
{
155155
writer.WriteStartObject();
156156

src/Microsoft.OpenApi/Models/OpenApiExtensibleDictionary.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using System.Text.Json.Nodes;
77
using Microsoft.OpenApi.Interfaces;
88
using Microsoft.OpenApi.Writers;
9-
using static Microsoft.OpenApi.Extensions.OpenApiSerializableExtensions;
109

1110
namespace Microsoft.OpenApi.Models
1211
{

src/Microsoft.OpenApi/Models/OpenApiExternalDocs.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

44
using System;

0 commit comments

Comments
 (0)