Skip to content

Commit 1ed02e3

Browse files
authored
Merge pull request #2398 from microsoft/fix/version-service-implementation-drift
fix: implementation drift between the different version services
2 parents 940945d + 2514526 commit 1ed02e3

File tree

4 files changed

+61
-73
lines changed

4 files changed

+61
-73
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
8+
namespace Microsoft.OpenApi.Reader;
9+
10+
internal abstract class BaseOpenApiVersionService : IOpenApiVersionService
11+
{
12+
public OpenApiDiagnostic Diagnostic { get; }
13+
14+
protected BaseOpenApiVersionService(OpenApiDiagnostic diagnostic)
15+
{
16+
Diagnostic = diagnostic;
17+
}
18+
19+
internal abstract Dictionary<Type, Func<ParseNode, OpenApiDocument, object?>> Loaders { get; }
20+
21+
public abstract OpenApiDocument LoadDocument(RootNode rootNode, Uri location);
22+
23+
public T? LoadElement<T>(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement
24+
{
25+
if (Loaders.TryGetValue(typeof(T), out var loader) && loader(node, doc) is T result)
26+
{
27+
return result;
28+
}
29+
return default;
30+
}
31+
public virtual string? GetReferenceScalarValues(MapNode mapNode, string scalarValue)
32+
{
33+
if (mapNode.Any(static x => !"$ref".Equals(x.Name, StringComparison.OrdinalIgnoreCase)) &&
34+
mapNode
35+
.Where(x => x.Name.Equals(scalarValue))
36+
.Select(static x => x.Value)
37+
.OfType<ValueNode>().FirstOrDefault() is {} valueNode)
38+
{
39+
return valueNode.GetScalarValue();
40+
}
41+
42+
return null;
43+
}
44+
}

src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,14 @@ namespace Microsoft.OpenApi.Reader.V2
1010
/// <summary>
1111
/// The version specific implementations for OpenAPI V2.0.
1212
/// </summary>
13-
internal class OpenApiV2VersionService : IOpenApiVersionService
13+
internal class OpenApiV2VersionService : BaseOpenApiVersionService
1414
{
15-
public OpenApiDiagnostic Diagnostic { get; }
16-
1715
/// <summary>
1816
/// Create Parsing Context
1917
/// </summary>
2018
/// <param name="diagnostic">Provide instance for diagnostic object for collecting and accessing information about the parsing.</param>
21-
public OpenApiV2VersionService(OpenApiDiagnostic diagnostic)
19+
public OpenApiV2VersionService(OpenApiDiagnostic diagnostic): base(diagnostic)
2220
{
23-
Diagnostic = diagnostic;
2421
}
2522

2623
private readonly Dictionary<Type, Func<ParseNode, OpenApiDocument, object?>> _loaders = new()
@@ -44,22 +41,13 @@ public OpenApiV2VersionService(OpenApiDiagnostic diagnostic)
4441
[typeof(OpenApiXml)] = OpenApiV2Deserializer.LoadXml
4542
};
4643

47-
public OpenApiDocument LoadDocument(RootNode rootNode, Uri location)
44+
public override OpenApiDocument LoadDocument(RootNode rootNode, Uri location)
4845
{
4946
return OpenApiV2Deserializer.LoadOpenApi(rootNode, location);
5047
}
48+
internal override Dictionary<Type, Func<ParseNode, OpenApiDocument, object?>> Loaders => _loaders;
5149

52-
public T? LoadElement<T>(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement
53-
{
54-
if (_loaders.TryGetValue(typeof(T), out var loader) && loader(node, doc) is T result)
55-
{
56-
return result;
57-
}
58-
return default;
59-
}
60-
61-
/// <inheritdoc />
62-
public string GetReferenceScalarValues(MapNode mapNode, string scalarValue)
50+
public override string GetReferenceScalarValues(MapNode mapNode, string scalarValue)
6351
{
6452
throw new InvalidOperationException();
6553
}

src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,24 @@
33

44
using System;
55
using System.Collections.Generic;
6-
using System.Linq;
76

87
namespace Microsoft.OpenApi.Reader.V3
98
{
109
/// <summary>
1110
/// The version service for the Open API V3.0.
1211
/// </summary>
13-
internal class OpenApiV3VersionService : IOpenApiVersionService
12+
internal class OpenApiV3VersionService : BaseOpenApiVersionService
1413
{
15-
public OpenApiDiagnostic Diagnostic { get; }
16-
17-
private static readonly char[] _pathSeparator = new char[] { '/' };
1814

1915
/// <summary>
2016
/// Create Parsing Context
2117
/// </summary>
2218
/// <param name="diagnostic">Provide instance for diagnostic object for collecting and accessing information about the parsing.</param>
23-
public OpenApiV3VersionService(OpenApiDiagnostic diagnostic)
19+
public OpenApiV3VersionService(OpenApiDiagnostic diagnostic):base(diagnostic)
2420
{
25-
Diagnostic = diagnostic;
2621
}
2722

28-
private readonly Dictionary<Type, Func<ParseNode, OpenApiDocument, object>> _loaders = new()
23+
private readonly Dictionary<Type, Func<ParseNode, OpenApiDocument, object?>> _loaders = new()
2924
{
3025
[typeof(JsonNodeExtension)] = OpenApiV3Deserializer.LoadAny,
3126
[typeof(OpenApiCallback)] = OpenApiV3Deserializer.LoadCallback,
@@ -59,29 +54,11 @@ public OpenApiV3VersionService(OpenApiDiagnostic diagnostic)
5954
[typeof(OpenApiSchemaReference)] = OpenApiV3Deserializer.LoadMapping
6055
};
6156

62-
public OpenApiDocument LoadDocument(RootNode rootNode, Uri location)
63-
{
64-
return OpenApiV3Deserializer.LoadOpenApi(rootNode, location);
65-
}
57+
internal override Dictionary<Type, Func<ParseNode, OpenApiDocument, object?>> Loaders => _loaders;
6658

67-
public T LoadElement<T>(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement
59+
public override OpenApiDocument LoadDocument(RootNode rootNode, Uri location)
6860
{
69-
return (T)_loaders[typeof(T)](node, doc);
61+
return OpenApiV3Deserializer.LoadOpenApi(rootNode, location);
7062
}
71-
72-
/// <inheritdoc />
73-
public string? GetReferenceScalarValues(MapNode mapNode, string scalarValue)
74-
{
75-
if (mapNode.Any(static x => !"$ref".Equals(x.Name, StringComparison.OrdinalIgnoreCase)) &&
76-
mapNode
77-
.Where(x => x.Name.Equals(scalarValue))
78-
.Select(static x => x.Value)
79-
.OfType<ValueNode>().FirstOrDefault() is {} valueNode)
80-
{
81-
return valueNode.GetScalarValue();
82-
}
83-
84-
return null;
85-
}
8663
}
8764
}

src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,30 @@
33

44
using System;
55
using System.Collections.Generic;
6-
using System.Linq;
7-
using Microsoft.OpenApi.Reader.V3;
86

97
namespace Microsoft.OpenApi.Reader.V31
108
{
119
/// <summary>
1210
/// The version service for the Open API V3.1.
1311
/// </summary>
14-
internal class OpenApiV31VersionService : IOpenApiVersionService
12+
internal class OpenApiV31VersionService : BaseOpenApiVersionService
1513
{
16-
public OpenApiDiagnostic Diagnostic { get; }
1714

1815
/// <summary>
1916
/// Create Parsing Context
2017
/// </summary>
2118
/// <param name="diagnostic">Provide instance for diagnotic object for collecting and accessing information about the parsing.</param>
22-
public OpenApiV31VersionService(OpenApiDiagnostic diagnostic)
19+
public OpenApiV31VersionService(OpenApiDiagnostic diagnostic):base(diagnostic)
2320
{
24-
Diagnostic = diagnostic;
2521
}
2622

27-
private readonly Dictionary<Type, Func<ParseNode, OpenApiDocument, object>> _loaders = new Dictionary<Type, Func<ParseNode, OpenApiDocument, object>>
23+
private readonly Dictionary<Type, Func<ParseNode, OpenApiDocument, object?>> _loaders = new Dictionary<Type, Func<ParseNode, OpenApiDocument, object?>>
2824
{
2925
[typeof(JsonNodeExtension)] = OpenApiV31Deserializer.LoadAny,
3026
[typeof(OpenApiCallback)] = OpenApiV31Deserializer.LoadCallback,
3127
[typeof(OpenApiComponents)] = OpenApiV31Deserializer.LoadComponents,
3228
[typeof(OpenApiContact)] = OpenApiV31Deserializer.LoadContact,
33-
[typeof(OpenApiDiscriminator)] = OpenApiV3Deserializer.LoadDiscriminator,
29+
[typeof(OpenApiDiscriminator)] = OpenApiV31Deserializer.LoadDiscriminator,
3430
[typeof(OpenApiEncoding)] = OpenApiV31Deserializer.LoadEncoding,
3531
[typeof(OpenApiExample)] = OpenApiV31Deserializer.LoadExample,
3632
[typeof(OpenApiExternalDocs)] = OpenApiV31Deserializer.LoadExternalDocs,
@@ -58,28 +54,11 @@ public OpenApiV31VersionService(OpenApiDiagnostic diagnostic)
5854
[typeof(OpenApiSchemaReference)] = OpenApiV31Deserializer.LoadMapping
5955
};
6056

61-
public OpenApiDocument LoadDocument(RootNode rootNode, Uri location)
57+
public override OpenApiDocument LoadDocument(RootNode rootNode, Uri location)
6258
{
6359
return OpenApiV31Deserializer.LoadOpenApi(rootNode, location);
6460
}
61+
internal override Dictionary<Type, Func<ParseNode, OpenApiDocument, object?>> Loaders => _loaders;
6562

66-
public T LoadElement<T>(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement
67-
{
68-
return (T)_loaders[typeof(T)](node, doc);
69-
}
70-
71-
/// <inheritdoc />
72-
public string? GetReferenceScalarValues(MapNode mapNode, string scalarValue)
73-
{
74-
if (mapNode.Any(static x => !"$ref".Equals(x.Name, StringComparison.OrdinalIgnoreCase)))
75-
{
76-
var valueNode = mapNode.Where(x => x.Name.Equals(scalarValue))
77-
.Select(static x => x.Value).OfType<ValueNode>().FirstOrDefault();
78-
79-
return valueNode?.GetScalarValue();
80-
}
81-
82-
return null;
83-
}
8463
}
8564
}

0 commit comments

Comments
 (0)