Skip to content

Commit 2baa14c

Browse files
committed
Use a callback to explicitly call the Serialize methods
1 parent 07d66aa commit 2baa14c

36 files changed

+226
-199
lines changed

src/Microsoft.OpenApi/Extensions/OpenApiSerializableExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ namespace Microsoft.OpenApi.Extensions
1515
/// </summary>
1616
public static class OpenApiSerializableExtensions
1717
{
18+
public delegate void SerializeDelegate(IOpenApiWriter writer, IOpenApiSerializable element);
19+
1820
/// <summary>
1921
/// Serialize the <see cref="IOpenApiSerializable"/> to the Open API document (JSON) using the given stream and specification version.
2022
/// </summary>

src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceable.cs

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

44
using Microsoft.OpenApi.Models;
55
using Microsoft.OpenApi.Writers;
6+
using static Microsoft.OpenApi.Extensions.OpenApiSerializableExtensions;
67

78
namespace Microsoft.OpenApi.Interfaces
89
{
@@ -25,7 +26,7 @@ public interface IOpenApiReferenceable : IOpenApiSerializable
2526
/// <summary>
2627
/// Serialize to OpenAPI V3 document without using reference.
2728
/// </summary>
28-
void SerializeAsV3WithoutReference(IOpenApiWriter writer, OpenApiSpecVersion version);
29+
void SerializeAsV3WithoutReference(IOpenApiWriter writer, OpenApiSpecVersion version, SerializeDelegate callback);
2930

3031
/// <summary>
3132
/// Serialize to OpenAPI V2 document without using reference.

src/Microsoft.OpenApi/Models/OpenApiCallback.cs

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

44
using System.Collections.Generic;
5-
using Microsoft.OpenApi.Any;
65
using Microsoft.OpenApi.Expressions;
76
using Microsoft.OpenApi.Interfaces;
87
using Microsoft.OpenApi.Writers;
8+
using static Microsoft.OpenApi.Extensions.OpenApiSerializableExtensions;
99

1010
namespace Microsoft.OpenApi.Models
1111
{
@@ -83,23 +83,24 @@ public void AddPathItem(RuntimeExpression expression, OpenApiPathItem pathItem)
8383
/// <exception cref="System.NotImplementedException"></exception>
8484
public void SerializeAsV31(IOpenApiWriter writer)
8585
{
86-
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1);
86+
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV3(writer));
8787
}
8888

8989
/// <summary>
9090
/// Serialize <see cref="OpenApiCallback"/> to Open Api v3.0
9191
/// </summary>
9292
public void SerializeAsV3(IOpenApiWriter writer)
9393
{
94-
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0);
94+
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
9595
}
9696

9797
/// <summary>
9898
/// Serialize <see cref="OpenApiCallback"/>
9999
/// </summary>
100100
/// <param name="writer"></param>
101101
/// <param name="version"></param>
102-
private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version)
102+
/// <param name="callback"></param>
103+
private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, SerializeDelegate callback)
103104
{
104105
writer = writer ?? throw Error.ArgumentNull(nameof(writer));
105106

@@ -109,15 +110,15 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
109110
{
110111
if (!writer.GetSettings().ShouldInlineReference(Reference))
111112
{
112-
Reference.SerializeAsV3(writer);
113+
callback(writer, Reference);
113114
return;
114115
}
115116
else
116117
{
117118
target = GetEffective(Reference.HostDocument);
118119
}
119120
}
120-
target.SerializeAsV3WithoutReference(writer, version);
121+
target.SerializeAsV3WithoutReference(writer, version, callback);
121122
}
122123

123124
/// <summary>
@@ -142,14 +143,14 @@ public OpenApiCallback GetEffective(OpenApiDocument doc)
142143
/// Serialize to OpenAPI V3 document without using reference.
143144
/// </summary>
144145

145-
public void SerializeAsV3WithoutReference(IOpenApiWriter writer, OpenApiSpecVersion version)
146+
public void SerializeAsV3WithoutReference(IOpenApiWriter writer, OpenApiSpecVersion version, SerializeDelegate callback)
146147
{
147148
writer.WriteStartObject();
148149

149150
// path items
150151
foreach (var item in PathItems)
151152
{
152-
writer.WriteRequiredObject(item.Key.Expression, item.Value, (w, p) => p.SerializeAsV3(w));
153+
writer.WriteRequiredObject(item.Key.Expression, item.Value, (w, p) => callback(w, p));
153154
}
154155

155156
// extensions

src/Microsoft.OpenApi/Models/OpenApiComponents.cs

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Linq;
77
using Microsoft.OpenApi.Interfaces;
88
using Microsoft.OpenApi.Writers;
9+
using static Microsoft.OpenApi.Extensions.OpenApiSerializableExtensions;
910

1011
namespace Microsoft.OpenApi.Models
1112
{
@@ -101,7 +102,7 @@ public OpenApiComponents(OpenApiComponents components)
101102
/// <param name="writer"></param>
102103
public void SerializeAsV31(IOpenApiWriter writer)
103104
{
104-
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1);
105+
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV3(writer));
105106

106107
// pathItems - only present in v3.1
107108
writer.WriteOptionalMap(
@@ -113,7 +114,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
113114
component.Reference.Type == ReferenceType.Schema &&
114115
component.Reference.Id == key)
115116
{
116-
component.SerializeAsV3WithoutReference(w, OpenApiSpecVersion.OpenApi3_1);
117+
component.SerializeAsV3WithoutReference(w, OpenApiSpecVersion.OpenApi3_1, callback: (w, e) => e.SerializeAsV3(w));
117118
}
118119
else
119120
{
@@ -130,14 +131,14 @@ public void SerializeAsV31(IOpenApiWriter writer)
130131
/// <param name="writer"></param>
131132
public void SerializeAsV3(IOpenApiWriter writer)
132133
{
133-
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0);
134+
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
134135
writer.WriteEndObject();
135136
}
136137

137138
/// <summary>
138139
/// Serialize <see cref="OpenApiComponents"/>.
139140
/// </summary>
140-
private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version)
141+
private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, SerializeDelegate callback)
141142
{
142143
writer = writer ?? throw Error.ArgumentNull(nameof(writer));
143144

@@ -156,7 +157,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
156157
OpenApiConstants.Schemas,
157158
Schemas,
158159
(w, key, component) => {
159-
component.SerializeAsV3WithoutReference(w, version);
160+
component.SerializeAsV3WithoutReference(w, version, callback);
160161
});
161162
}
162163
writer.WriteEndObject();
@@ -178,11 +179,11 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
178179
component.Reference.Type == ReferenceType.Schema &&
179180
component.Reference.Id == key)
180181
{
181-
component.SerializeAsV3WithoutReference(w, version);
182+
component.SerializeAsV3WithoutReference(w, version, callback);
182183
}
183184
else
184185
{
185-
component.SerializeAsV3(w);
186+
callback(w, component);
186187
}
187188
});
188189

@@ -196,11 +197,11 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
196197
component.Reference.Type == ReferenceType.Response &&
197198
component.Reference.Id == key)
198199
{
199-
component.SerializeAsV3WithoutReference(w, version);
200+
component.SerializeAsV3WithoutReference(w, version, callback);
200201
}
201202
else
202203
{
203-
component.SerializeAsV3(w);
204+
callback(w, component);
204205
}
205206
});
206207

@@ -214,11 +215,11 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
214215
component.Reference.Type == ReferenceType.Parameter &&
215216
component.Reference.Id == key)
216217
{
217-
component.SerializeAsV3WithoutReference(w, version);
218+
component.SerializeAsV3WithoutReference(w, version, callback);
218219
}
219220
else
220221
{
221-
component.SerializeAsV3(w);
222+
callback(w, component);
222223
}
223224
});
224225

@@ -232,11 +233,11 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
232233
component.Reference.Type == ReferenceType.Example &&
233234
component.Reference.Id == key)
234235
{
235-
component.SerializeAsV3WithoutReference(w, version);
236+
component.SerializeAsV3WithoutReference(w, version, callback);
236237
}
237238
else
238239
{
239-
component.SerializeAsV3(w);
240+
callback(w, component);
240241
}
241242
});
242243

@@ -250,11 +251,11 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
250251
component.Reference.Type == ReferenceType.RequestBody &&
251252
component.Reference.Id == key)
252253
{
253-
component.SerializeAsV3WithoutReference(w, version);
254+
component.SerializeAsV3WithoutReference(w, version, callback);
254255
}
255256
else
256257
{
257-
component.SerializeAsV3(w);
258+
callback(w, component);
258259
}
259260
});
260261

@@ -268,11 +269,11 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
268269
component.Reference.Type == ReferenceType.Header &&
269270
component.Reference.Id == key)
270271
{
271-
component.SerializeAsV3WithoutReference(w, version);
272+
component.SerializeAsV3WithoutReference(w, version, callback);
272273
}
273274
else
274275
{
275-
component.SerializeAsV3(w);
276+
callback(w, component);
276277
}
277278
});
278279

@@ -286,11 +287,11 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
286287
component.Reference.Type == ReferenceType.SecurityScheme &&
287288
component.Reference.Id == key)
288289
{
289-
component.SerializeAsV3WithoutReference(w, version);
290+
component.SerializeAsV3WithoutReference(w, version, callback);
290291
}
291292
else
292293
{
293-
component.SerializeAsV3(w);
294+
callback(w, component);
294295
}
295296
});
296297

@@ -304,11 +305,11 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
304305
component.Reference.Type == ReferenceType.Link &&
305306
component.Reference.Id == key)
306307
{
307-
component.SerializeAsV3WithoutReference(w, version);
308+
component.SerializeAsV3WithoutReference(w, version, callback);
308309
}
309310
else
310311
{
311-
component.SerializeAsV3(w);
312+
callback(w, component);
312313
}
313314
});
314315

@@ -322,11 +323,11 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
322323
component.Reference.Type == ReferenceType.Callback &&
323324
component.Reference.Id == key)
324325
{
325-
component.SerializeAsV3WithoutReference(w, version);
326+
component.SerializeAsV3WithoutReference(w, version, callback);
326327
}
327328
else
328329
{
329-
component.SerializeAsV3(w);
330+
callback(w, component);
330331
}
331332
});
332333

src/Microsoft.OpenApi/Models/OpenApiDocument.cs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Microsoft.OpenApi.Interfaces;
1212
using Microsoft.OpenApi.Services;
1313
using Microsoft.OpenApi.Writers;
14+
using static Microsoft.OpenApi.Extensions.OpenApiSerializableExtensions;
1415

1516
namespace Microsoft.OpenApi.Models
1617
{
@@ -121,7 +122,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
121122
// jsonSchemaDialect
122123
writer.WriteProperty(OpenApiConstants.JsonSchemaDialect, JsonSchemaDialect);
123124

124-
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1);
125+
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (w, element) => element.SerializeAsV31(w));
125126

126127
// webhooks
127128
writer.WriteOptionalMap(
@@ -133,7 +134,7 @@ public void SerializeAsV31(IOpenApiWriter writer)
133134
component.Reference.Type == ReferenceType.PathItem &&
134135
component.Reference.Id == key)
135136
{
136-
component.SerializeAsV3WithoutReference(w, OpenApiSpecVersion.OpenApi3_1);
137+
component.SerializeAsV3WithoutReference(w, OpenApiSpecVersion.OpenApi3_1, callback: (w, e) => e.SerializeAsV3(w));
137138
}
138139
else
139140
{
@@ -156,7 +157,7 @@ public void SerializeAsV3(IOpenApiWriter writer)
156157

157158
// openapi
158159
writer.WriteProperty(OpenApiConstants.OpenApi, "3.0.1");
159-
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0);
160+
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (w, element) => element.SerializeAsV3(w));
160161
writer.WriteEndObject();
161162
}
162163

@@ -165,31 +166,32 @@ public void SerializeAsV3(IOpenApiWriter writer)
165166
/// </summary>
166167
/// <param name="writer"></param>
167168
/// <param name="version"></param>
168-
private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version)
169+
/// <param name="callback"></param>
170+
private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, SerializeDelegate callback)
169171
{
170172
// info
171-
writer.WriteRequiredObject(OpenApiConstants.Info, Info, (w, i) => i.SerializeAsV3(w));
173+
writer.WriteRequiredObject(OpenApiConstants.Info, Info, (w, i) => callback(w, i));
172174

173175
// servers
174-
writer.WriteOptionalCollection(OpenApiConstants.Servers, Servers, (w, s) => s.SerializeAsV3(w));
176+
writer.WriteOptionalCollection(OpenApiConstants.Servers, Servers, (w, s) => callback(w, s));
175177

176178
// paths
177-
writer.WriteRequiredObject(OpenApiConstants.Paths, Paths, (w, p) => p.SerializeAsV3(w));
179+
writer.WriteRequiredObject(OpenApiConstants.Paths, Paths, (w, p) => callback(w, p));
178180

179181
// components
180-
writer.WriteOptionalObject(OpenApiConstants.Components, Components, (w, c) => c.SerializeAsV3(w));
182+
writer.WriteOptionalObject(OpenApiConstants.Components, Components, (w, c) => callback(w, c));
181183

182184
// security
183185
writer.WriteOptionalCollection(
184186
OpenApiConstants.Security,
185187
SecurityRequirements,
186-
(w, s) => s.SerializeAsV3(w));
188+
(w, s) => callback(w, s));
187189

188190
// tags
189-
writer.WriteOptionalCollection(OpenApiConstants.Tags, Tags, (w, t) => t.SerializeAsV3WithoutReference(w, version));
191+
writer.WriteOptionalCollection(OpenApiConstants.Tags, Tags, (w, t) => t.SerializeAsV3WithoutReference(w, version, callback));
190192

191193
// external docs
192-
writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, e) => e.SerializeAsV3(w));
194+
writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, e) => callback(w, e));
193195

194196
// extensions
195197
writer.WriteExtensions(Extensions, OpenApiSpecVersion.OpenApi3_0);

src/Microsoft.OpenApi/Models/OpenApiEncoding.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.OpenApi.Extensions;
77
using Microsoft.OpenApi.Interfaces;
88
using Microsoft.OpenApi.Writers;
9+
using static Microsoft.OpenApi.Extensions.OpenApiSerializableExtensions;
910

1011
namespace Microsoft.OpenApi.Models
1112
{
@@ -77,7 +78,7 @@ public OpenApiEncoding(OpenApiEncoding encoding)
7778
/// <param name="writer"></param>
7879
public void SerializeAsV31(IOpenApiWriter writer)
7980
{
80-
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1);
81+
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer));
8182
}
8283

8384
/// <summary>
@@ -86,13 +87,13 @@ public void SerializeAsV31(IOpenApiWriter writer)
8687
/// <param name="writer"></param>
8788
public void SerializeAsV3(IOpenApiWriter writer)
8889
{
89-
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0);
90+
SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer));
9091
}
9192

9293
/// <summary>
9394
/// Serialize <see cref="OpenApiExternalDocs"/> to Open Api v3.0.
9495
/// </summary>
95-
private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version)
96+
private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version, SerializeDelegate callback)
9697
{
9798
writer = writer ?? throw Error.ArgumentNull(nameof(writer));
9899

@@ -102,7 +103,7 @@ private void SerializeInternal(IOpenApiWriter writer, OpenApiSpecVersion version
102103
writer.WriteProperty(OpenApiConstants.ContentType, ContentType);
103104

104105
// headers
105-
writer.WriteOptionalMap(OpenApiConstants.Headers, Headers, (w, h) => h.SerializeAsV3(w));
106+
writer.WriteOptionalMap(OpenApiConstants.Headers, Headers, (w, h) => callback(w, h));
106107

107108
// style
108109
writer.WriteProperty(OpenApiConstants.Style, Style?.GetDisplayName());

0 commit comments

Comments
 (0)