Skip to content

Commit 7ca70f2

Browse files
committed
Added support for custom extensions
1 parent 6341fdb commit 7ca70f2

Some content is hidden

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

47 files changed

+327
-40
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Microsoft.OpenApi.Any;
2+
using Microsoft.OpenApi.Interfaces;
3+
using Microsoft.OpenApi.Readers.ParseNodes;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
10+
namespace Microsoft.OpenApi.Readers
11+
{
12+
/// <summary>
13+
/// Configuration settings to control how OpenAPI documents are parsed
14+
/// </summary>
15+
public class OpenApiReaderSettings
16+
{
17+
/// <summary>
18+
/// Dictionary of parsers for converting extensions into strongly typed classes
19+
/// </summary>
20+
public Dictionary<string, Func<IOpenApiAny , IOpenApiExtension>> ExtensionParsers { get; set; } = new Dictionary<string, Func<IOpenApiAny, IOpenApiExtension>>();
21+
22+
}
23+
}

src/Microsoft.OpenApi.Readers/OpenApiStreamReader.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,17 @@ namespace Microsoft.OpenApi.Readers
1515
/// </summary>
1616
public class OpenApiStreamReader : IOpenApiReader<Stream, OpenApiDiagnostic>
1717
{
18+
private OpenApiReaderSettings _settings;
1819

20+
/// <summary>
21+
///
22+
/// </summary>
23+
/// <param name="settings"></param>
24+
public OpenApiStreamReader(OpenApiReaderSettings settings = null)
25+
{
26+
_settings = settings ?? new OpenApiReaderSettings();
27+
28+
}
1929
/// <summary>
2030
/// Reads the stream input and parses it into an Open API document.
2131
/// </summary>
@@ -38,7 +48,10 @@ public OpenApiDocument Read(Stream input, out OpenApiDiagnostic diagnostic)
3848
return new OpenApiDocument();
3949
}
4050

41-
context = new ParsingContext();
51+
context = new ParsingContext
52+
{
53+
ExtensionParsers = _settings.ExtensionParsers
54+
};
4255
return context.Parse(yamlDocument, diagnostic);
4356
}
4457

src/Microsoft.OpenApi.Readers/OpenApiStringReader.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@ namespace Microsoft.OpenApi.Readers
1212
/// </summary>
1313
public class OpenApiStringReader : IOpenApiReader<string, OpenApiDiagnostic>
1414
{
15+
private readonly OpenApiReaderSettings _settings;
16+
17+
/// <summary>
18+
/// Constructor tha allows reader to use non-default settings
19+
/// </summary>
20+
/// <param name="settings"></param>
21+
public OpenApiStringReader(OpenApiReaderSettings settings = null)
22+
{
23+
_settings = settings ?? new OpenApiReaderSettings();
24+
}
25+
1526
/// <summary>
1627
/// Reads the string input and parses it into an Open API document.
1728
/// </summary>
@@ -24,7 +35,7 @@ public OpenApiDocument Read(string input, out OpenApiDiagnostic diagnostic)
2435
writer.Flush();
2536
memoryStream.Position = 0;
2637

27-
return new OpenApiStreamReader().Read(memoryStream, out diagnostic);
38+
return new OpenApiStreamReader(_settings).Read(memoryStream, out diagnostic);
2839
}
2940
}
3041
}

src/Microsoft.OpenApi.Readers/ParsingContext.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Linq;
7+
using Microsoft.OpenApi.Any;
78
using Microsoft.OpenApi.Interfaces;
89
using Microsoft.OpenApi.Models;
910
using Microsoft.OpenApi.Readers.Interface;
@@ -23,6 +24,9 @@ public class ParsingContext
2324
private readonly Dictionary<string, IOpenApiReferenceable> _referenceStore = new Dictionary<string, IOpenApiReferenceable>();
2425
private readonly Dictionary<string, object> _tempStorage = new Dictionary<string, object>();
2526
private IOpenApiVersionService _versionService;
27+
28+
internal Dictionary<string, Func<IOpenApiAny, IOpenApiExtension>> ExtensionParsers { get; set; } = new Dictionary<string, Func<IOpenApiAny, IOpenApiExtension>>();
29+
2630
internal RootNode RootNode { get; set; }
2731
internal List<OpenApiTag> Tags { get; private set; } = new List<OpenApiTag>();
2832

@@ -61,6 +65,7 @@ internal OpenApiDocument Parse(YamlDocument yamlDocument, OpenApiDiagnostic diag
6165
return doc;
6266
}
6367

68+
6469
/// <summary>
6570
/// Gets the version of the Open API document.
6671
/// </summary>

src/Microsoft.OpenApi.Readers/V3/OpenApiDocumentDeserializer.cs

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

44
using System.Collections.Generic;
5+
using Microsoft.OpenApi.Any;
56
using Microsoft.OpenApi.Extensions;
7+
using Microsoft.OpenApi.Interfaces;
68
using Microsoft.OpenApi.Models;
79
using Microsoft.OpenApi.Readers.ParseNodes;
810

@@ -50,5 +52,17 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode)
5052

5153
return openApidoc;
5254
}
55+
56+
57+
public static IOpenApiExtension LoadExtension(string name, ParseNode node)
58+
{
59+
if (node.Context.ExtensionParsers.TryGetValue(name, out var parser)) {
60+
return parser(node.CreateAny());
61+
}
62+
else
63+
{
64+
return node.CreateAny();
65+
}
66+
}
5367
}
5468
}

src/Microsoft.OpenApi.Readers/V3/OpenApiInfoDeserializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ internal static partial class OpenApiV3Deserializer
5757

5858
public static PatternFieldMap<OpenApiInfo> InfoPatternFields = new PatternFieldMap<OpenApiInfo>
5959
{
60-
{s => s.StartsWith("x-"), (o, k, n) => o.AddExtension(k, n.CreateAny())}
60+
{s => s.StartsWith("x-"), (o, k, n) => o.Extensions.Add(k,LoadExtension(k, n))}
6161
};
6262

6363
public static OpenApiInfo LoadInfo(ParseNode node)

src/Microsoft.OpenApi/Any/IOpenApiAny.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Microsoft.OpenApi.Any
88
/// <summary>
99
/// Base interface for all the types that represent Open API Any.
1010
/// </summary>
11-
public interface IOpenApiAny : IOpenApiElement
11+
public interface IOpenApiAny : IOpenApiElement, IOpenApiExtension
1212
{
1313
/// <summary>
1414
/// Type of an <see cref="IOpenApiAny"/>.

src/Microsoft.OpenApi/Any/OpenApiArray.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4+
using Microsoft.OpenApi.Writers;
45
using System.Collections.Generic;
56

67
namespace Microsoft.OpenApi.Any
@@ -14,5 +15,22 @@ public class OpenApiArray : List<IOpenApiAny>, IOpenApiAny
1415
/// The type of <see cref="IOpenApiAny"/>
1516
/// </summary>
1617
public AnyType AnyType { get; } = AnyType.Array;
18+
19+
/// <summary>
20+
/// Write out contents of OpenApiArray to passed writer
21+
/// </summary>
22+
/// <param name="writer">Instance of JSON or YAML writer.</param>
23+
public void Write(IOpenApiWriter writer)
24+
{
25+
writer.WriteStartArray();
26+
27+
foreach (var item in this)
28+
{
29+
writer.WriteAny(item);
30+
}
31+
32+
writer.WriteEndArray();
33+
34+
}
1735
}
1836
}

src/Microsoft.OpenApi/Any/OpenApiNull.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4+
using Microsoft.OpenApi.Writers;
5+
46
namespace Microsoft.OpenApi.Any
57
{
68
/// <summary>
@@ -12,5 +14,14 @@ public class OpenApiNull : IOpenApiAny
1214
/// The type of <see cref="IOpenApiAny"/>
1315
/// </summary>
1416
public AnyType AnyType { get; } = AnyType.Null;
17+
18+
/// <summary>
19+
/// Write out null representation
20+
/// </summary>
21+
/// <param name="writer"></param>
22+
public void Write(IOpenApiWriter writer)
23+
{
24+
writer.WriteAny(this);
25+
}
1526
}
1627
}

src/Microsoft.OpenApi/Any/OpenApiObject.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license.
33

44
using System.Collections.Generic;
5+
using Microsoft.OpenApi.Writers;
56

67
namespace Microsoft.OpenApi.Any
78
{
@@ -14,5 +15,23 @@ public class OpenApiObject : Dictionary<string, IOpenApiAny>, IOpenApiAny
1415
/// Type of <see cref="IOpenApiAny"/>.
1516
/// </summary>
1617
public AnyType AnyType { get; } = AnyType.Object;
18+
19+
/// <summary>
20+
///
21+
/// </summary>
22+
/// <param name="writer"></param>
23+
public void Write(IOpenApiWriter writer)
24+
{
25+
writer.WriteStartObject();
26+
27+
foreach (var item in this)
28+
{
29+
writer.WritePropertyName(item.Key);
30+
writer.WriteAny(item.Value);
31+
}
32+
33+
writer.WriteEndObject();
34+
35+
}
1736
}
1837
}

0 commit comments

Comments
 (0)