Skip to content

Commit f3c693a

Browse files
authored
Merge branch 'vnext' into dm/vnext/fix272
2 parents b851c14 + 0fb9f1d commit f3c693a

File tree

3 files changed

+103
-6
lines changed

3 files changed

+103
-6
lines changed

src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ namespace Microsoft.OpenApi.Services
1515
public abstract class OpenApiVisitorBase
1616
{
1717
private readonly Stack<string> _path = new Stack<string>();
18-
18+
19+
/// <summary>
20+
/// Properties available to identify context of where an object is within OpenAPI Document
21+
/// </summary>
22+
public CurrentKeys CurrentKeys { get; } = new CurrentKeys();
23+
1924
/// <summary>
2025
/// Allow Rule to indicate validation error occured at a deeper context level.
2126
/// </summary>
@@ -44,8 +49,6 @@ public string PathString
4449
}
4550
}
4651

47-
48-
4952
/// <summary>
5053
/// Visits <see cref="OpenApiDocument"/>
5154
/// </summary>

src/Microsoft.OpenApi/Services/OpenApiWalker.cs

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class OpenApiWalker
1818
private readonly OpenApiVisitorBase _visitor;
1919
private readonly Stack<OpenApiSchema> _schemaLoop = new Stack<OpenApiSchema>();
2020
private readonly Stack<OpenApiPathItem> _pathItemLoop = new Stack<OpenApiPathItem>();
21+
2122
private bool _inComponents = false;
2223

2324
/// <summary>
@@ -53,6 +54,7 @@ public void Walk(OpenApiDocument doc)
5354
Walk(OpenApiConstants.ExternalDocs, () => Walk(doc.ExternalDocs));
5455
Walk(OpenApiConstants.Tags, () => Walk(doc.Tags));
5556
Walk(doc as IOpenApiExtensible);
57+
5658
}
5759

5860
/// <summary>
@@ -75,7 +77,6 @@ internal void Walk(IList<OpenApiTag> tags)
7577
Walk(i.ToString(), () => Walk(tags[i]));
7678
}
7779
}
78-
7980
}
8081

8182
/// <summary>
@@ -219,7 +220,9 @@ internal void Walk(OpenApiPaths paths)
219220
{
220221
foreach (var pathItem in paths)
221222
{
223+
_visitor.CurrentKeys.Path = pathItem.Key;
222224
Walk(pathItem.Key, () => Walk(pathItem.Value));// JSON Pointer uses ~1 as an escape character for /
225+
_visitor.CurrentKeys.Path = null;
223226
}
224227
}
225228
}
@@ -280,7 +283,9 @@ internal void Walk(IOpenApiExtensible openApiExtensible)
280283
{
281284
foreach (var item in openApiExtensible.Extensions)
282285
{
286+
_visitor.CurrentKeys.Extension = item.Key;
283287
Walk(item.Key, () => Walk(item.Value));
288+
_visitor.CurrentKeys.Extension = null;
284289
}
285290
}
286291
}
@@ -340,8 +345,10 @@ internal void Walk(OpenApiCallback callback)
340345
{
341346
foreach (var item in callback.PathItems)
342347
{
348+
_visitor.CurrentKeys.Callback = item.Key.ToString();
343349
var pathItem = item.Value;
344350
Walk(item.Key.ToString(), () => Walk(pathItem));
351+
_visitor.CurrentKeys.Callback = null;
345352
}
346353
}
347354
}
@@ -392,7 +399,9 @@ internal void Walk(IDictionary<string,OpenApiServerVariable> serverVariables)
392399
{
393400
foreach (var variable in serverVariables)
394401
{
402+
_visitor.CurrentKeys.ServerVariable = variable.Key;
395403
Walk(variable.Key, () => Walk(variable.Value));
404+
_visitor.CurrentKeys.ServerVariable = null;
396405
}
397406
}
398407
}
@@ -457,7 +466,9 @@ internal void Walk(IDictionary<OperationType, OpenApiOperation> operations)
457466
{
458467
foreach (var operation in operations)
459468
{
469+
_visitor.CurrentKeys.Operation = operation.Key;
460470
Walk(operation.Key.GetDisplayName(), () => Walk(operation.Value));
471+
_visitor.CurrentKeys.Operation = null;
461472
}
462473
}
463474
}
@@ -561,7 +572,9 @@ internal void Walk(OpenApiResponses responses)
561572
{
562573
foreach (var response in responses)
563574
{
575+
_visitor.CurrentKeys.Response = response.Key;
564576
Walk(response.Key, () => Walk(response.Value));
577+
_visitor.CurrentKeys.Response = null;
565578
}
566579
}
567580
Walk(responses as IOpenApiExtensible);
@@ -622,7 +635,9 @@ internal void Walk(IDictionary<string, OpenApiHeader> headers)
622635
{
623636
foreach (var header in headers)
624637
{
638+
_visitor.CurrentKeys.Header = header.Key;
625639
Walk(header.Key, () => Walk(header.Value));
640+
_visitor.CurrentKeys.Header = null;
626641
}
627642
}
628643
}
@@ -640,9 +655,11 @@ internal void Walk(IDictionary<string, OpenApiCallback> callbacks)
640655
_visitor.Visit(callbacks);
641656
if (callbacks != null)
642657
{
643-
foreach (var header in callbacks)
658+
foreach (var callback in callbacks)
644659
{
645-
Walk(header.Key, () => Walk(header.Value));
660+
_visitor.CurrentKeys.Callback = callback.Key;
661+
Walk(callback.Key, () => Walk(callback.Value));
662+
_visitor.CurrentKeys.Callback = null;
646663
}
647664
}
648665
}
@@ -662,7 +679,9 @@ internal void Walk(IDictionary<string, OpenApiMediaType> content)
662679
{
663680
foreach (var mediaType in content)
664681
{
682+
_visitor.CurrentKeys.Content = mediaType.Key;
665683
Walk(mediaType.Key, () => Walk(mediaType.Value));
684+
_visitor.CurrentKeys.Content = null;
666685
}
667686
}
668687
}
@@ -701,7 +720,9 @@ internal void Walk(IDictionary<string, OpenApiEncoding> encodings)
701720
{
702721
foreach (var item in encodings)
703722
{
723+
_visitor.CurrentKeys.Encoding = item.Key;
704724
Walk(item.Key, () => Walk(item.Value));
725+
_visitor.CurrentKeys.Encoding = null;
705726
}
706727
}
707728
}
@@ -787,7 +808,9 @@ internal void Walk(IDictionary<string,OpenApiExample> examples)
787808
{
788809
foreach (var example in examples)
789810
{
811+
_visitor.CurrentKeys.Example = example.Key;
790812
Walk(example.Key, () => Walk(example.Value));
813+
_visitor.CurrentKeys.Example = null;
791814
}
792815
}
793816
}
@@ -904,7 +927,9 @@ internal void Walk(IDictionary<string,OpenApiLink> links)
904927
{
905928
foreach (var item in links)
906929
{
930+
_visitor.CurrentKeys.Link = item.Key;
907931
Walk(item.Key, () => Walk(item.Value));
932+
_visitor.CurrentKeys.Link = null;
908933
}
909934
}
910935
}
@@ -1045,4 +1070,65 @@ private void ExitComponents()
10451070
_inComponents = false;
10461071
}
10471072
}
1073+
1074+
/// <summary>
1075+
/// Object containing contextual information based on where the walker is currently referencing in an OpenApiDocument
1076+
/// </summary>
1077+
public class CurrentKeys
1078+
{
1079+
/// <summary>
1080+
/// Current Path key
1081+
/// </summary>
1082+
public string Path { get; set; }
1083+
1084+
/// <summary>
1085+
/// Current Operation Type
1086+
/// </summary>
1087+
public OperationType? Operation { get; set; }
1088+
1089+
/// <summary>
1090+
/// Current Response Status Code
1091+
/// </summary>
1092+
public string Response { get; set; }
1093+
1094+
/// <summary>
1095+
/// Current Content Media Type
1096+
/// </summary>
1097+
public string Content { get; set; }
1098+
1099+
/// <summary>
1100+
/// Current Callback Key
1101+
/// </summary>
1102+
public string Callback { get; set; }
1103+
1104+
/// <summary>
1105+
/// Current Link Key
1106+
/// </summary>
1107+
public string Link { get; set; }
1108+
1109+
/// <summary>
1110+
/// Current Header Key
1111+
/// </summary>
1112+
public string Header { get; internal set; }
1113+
1114+
/// <summary>
1115+
/// Current Encoding Key
1116+
/// </summary>
1117+
public string Encoding { get; internal set; }
1118+
1119+
/// <summary>
1120+
/// Current Example Key
1121+
/// </summary>
1122+
public string Example { get; internal set; }
1123+
1124+
/// <summary>
1125+
/// Current Extension Key
1126+
/// </summary>
1127+
public string Extension { get; internal set; }
1128+
1129+
/// <summary>
1130+
/// Current ServerVariable
1131+
/// </summary>
1132+
public string ServerVariable { get; internal set; }
1133+
}
10481134
}

test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ public void LocatePathOperationContentSchema()
107107
"#/paths/~1test/get/responses/200/content/application~1json/schema",
108108

109109
});
110+
111+
locator.Keys.ShouldAllBeEquivalentTo(new List<string> { "/test","Get","200", "application/json" });
110112
}
111113

112114
[Fact]
@@ -153,6 +155,8 @@ public void WalkDOMWithCycles()
153155
internal class LocatorVisitor : OpenApiVisitorBase
154156
{
155157
public List<string> Locations = new List<string>();
158+
public List<string> Keys = new List<string>();
159+
156160
public override void Visit(OpenApiInfo info)
157161
{
158162
Locations.Add(this.PathString);
@@ -175,6 +179,7 @@ public override void Visit(OpenApiPaths paths)
175179

176180
public override void Visit(OpenApiPathItem pathItem)
177181
{
182+
Keys.Add(CurrentKeys.Path);
178183
Locations.Add(this.PathString);
179184
}
180185

@@ -185,10 +190,12 @@ public override void Visit(OpenApiResponses responses)
185190

186191
public override void Visit(OpenApiOperation operation)
187192
{
193+
Keys.Add(CurrentKeys.Operation.ToString());
188194
Locations.Add(this.PathString);
189195
}
190196
public override void Visit(OpenApiResponse response)
191197
{
198+
Keys.Add(CurrentKeys.Response);
192199
Locations.Add(this.PathString);
193200
}
194201

@@ -199,6 +206,7 @@ public override void Visit(IDictionary<string,OpenApiMediaType> content)
199206

200207
public override void Visit(OpenApiMediaType mediaType)
201208
{
209+
Keys.Add(CurrentKeys.Content);
202210
Locations.Add(this.PathString);
203211
}
204212

0 commit comments

Comments
 (0)