Skip to content

Commit c1b1616

Browse files
Merge pull request #1603 from microsoft/mk/use-proxy-reference-for-ref-resolution
Use proxy references to resolve references
2 parents 624814d + 27f4aa2 commit c1b1616

File tree

171 files changed

+1578
-1631
lines changed

Some content is hidden

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

171 files changed

+1578
-1631
lines changed

src/Microsoft.OpenApi.Hidi/OpenApiService.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ public static async Task TransformOpenApiDocument(HidiOptions options, ILogger l
6060
if (options.Output == null)
6161
{
6262
#pragma warning disable CA1308 // Normalize strings to uppercase
63-
var inputExtension = string.Concat(".", options.OpenApiFormat?.GetDisplayName().ToLowerInvariant())
64-
?? GetInputPathExtension(options.OpenApi, options.Csdl);
63+
var extension = options.OpenApiFormat?.GetDisplayName().ToLowerInvariant();
64+
var inputExtension = !string.IsNullOrEmpty(extension) ? string.Concat(".", extension)
65+
: GetInputPathExtension(options.OpenApi, options.Csdl);
66+
6567
#pragma warning restore CA1308 // Normalize strings to uppercase
6668
options.Output = new($"./output{inputExtension}");
6769
};

src/Microsoft.OpenApi/Interfaces/IEffective.cs

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ internal interface IOpenApiVersionService
2626
/// </summary>
2727
/// <typeparam name="T">Type of element to load</typeparam>
2828
/// <param name="node">document fragment node</param>
29+
/// <param name="doc">A host document instance.</param>
2930
/// <returns>Instance of OpenAPIElement</returns>
30-
T LoadElement<T>(ParseNode node) where T : IOpenApiElement;
31+
T LoadElement<T>(ParseNode node, OpenApiDocument doc = null) where T : IOpenApiElement;
3132

3233
/// <summary>
3334
/// Converts a generic RootNode instance into a strongly typed OpenApiDocument

src/Microsoft.OpenApi/Models/OpenApiCallback.cs

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Microsoft.OpenApi.Models
1212
/// <summary>
1313
/// Callback Object: A map of possible out-of band callbacks related to the parent operation.
1414
/// </summary>
15-
public class OpenApiCallback : IOpenApiReferenceable, IOpenApiExtensible, IEffective<OpenApiCallback>
15+
public class OpenApiCallback : IOpenApiReferenceable, IOpenApiExtensible
1616
{
1717
/// <summary>
1818
/// A Path Item Object used to define a callback request and expected responses.
@@ -61,10 +61,7 @@ public void AddPathItem(RuntimeExpression expression, OpenApiPathItem pathItem)
6161
Utils.CheckArgumentNull(expression);
6262
Utils.CheckArgumentNull(pathItem);
6363

64-
if (PathItems == null)
65-
{
66-
PathItems = new();
67-
}
64+
PathItems ??= new();
6865

6966
PathItems.Add(expression, pathItem);
7067
}
@@ -102,40 +99,9 @@ private void SerializeInternal(IOpenApiWriter writer,
10299
Utils.CheckArgumentNull(writer);
103100

104101
var target = this;
105-
106-
if (Reference != null)
107-
{
108-
if (!writer.GetSettings().ShouldInlineReference(Reference))
109-
{
110-
callback(writer, Reference);
111-
return;
112-
}
113-
else
114-
{
115-
target = GetEffective(Reference.HostDocument);
116-
}
117-
}
118-
119102
action(writer, target);
120103
}
121104

122-
/// <summary>
123-
/// Returns an effective OpenApiCallback object based on the presence of a $ref
124-
/// </summary>
125-
/// <param name="doc">The host OpenApiDocument that contains the reference.</param>
126-
/// <returns>OpenApiCallback</returns>
127-
public OpenApiCallback GetEffective(OpenApiDocument doc)
128-
{
129-
if (Reference != null)
130-
{
131-
return doc.ResolveReferenceTo<OpenApiCallback>(Reference);
132-
}
133-
else
134-
{
135-
return this;
136-
}
137-
}
138-
139105
/// <summary>
140106
/// Serialize to OpenAPI V31 document without using reference.
141107
/// </summary>

src/Microsoft.OpenApi/Models/OpenApiDocument.cs

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,16 @@ public IEnumerable<OpenApiError> ResolveReferences()
455455
return resolver.Errors;
456456
}
457457

458+
/// <summary>
459+
/// Walks the OpenApiDocument and sets the host document for all referenceable objects
460+
/// </summary>
461+
public void SetHostDocument()
462+
{
463+
var resolver = new HostDocumentResolver(this);
464+
var walker = new OpenApiWalker(resolver);
465+
walker.Walk(this);
466+
}
467+
458468
/// <summary>
459469
/// Load the referenced <see cref="IOpenApiReferenceable"/> object from a <see cref="OpenApiReference"/> object
460470
/// </summary>
@@ -562,49 +572,30 @@ internal IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool
562572
switch (reference.Type)
563573
{
564574
case ReferenceType.PathItem:
565-
var resolvedPathItem = this.Components.PathItems[reference.Id];
566-
resolvedPathItem.Description = reference.Description ?? resolvedPathItem.Description;
567-
resolvedPathItem.Summary = reference.Summary ?? resolvedPathItem.Summary;
568-
return resolvedPathItem;
569-
575+
return Components.PathItems[reference.Id];
570576
case ReferenceType.Response:
571-
var resolvedResponse = this.Components.Responses[reference.Id];
572-
resolvedResponse.Description = reference.Description ?? resolvedResponse.Description;
573-
return resolvedResponse;
577+
return Components.Responses[reference.Id];
574578

575579
case ReferenceType.Parameter:
576-
var resolvedParameter = this.Components.Parameters[reference.Id];
577-
resolvedParameter.Description = reference.Description ?? resolvedParameter.Description;
578-
return resolvedParameter;
580+
return Components.Parameters[reference.Id];
579581

580582
case ReferenceType.Example:
581-
var resolvedExample = this.Components.Examples[reference.Id];
582-
resolvedExample.Summary = reference.Summary ?? resolvedExample.Summary;
583-
resolvedExample.Description = reference.Description ?? resolvedExample.Description;
584-
return resolvedExample;
583+
return Components.Examples[reference.Id];
585584

586585
case ReferenceType.RequestBody:
587-
var resolvedRequestBody = this.Components.RequestBodies[reference.Id];
588-
resolvedRequestBody.Description = reference.Description ?? resolvedRequestBody.Description;
589-
return resolvedRequestBody;
586+
return Components.RequestBodies[reference.Id];
590587

591588
case ReferenceType.Header:
592-
var resolvedHeader = this.Components.Headers[reference.Id];
593-
resolvedHeader.Description = reference.Description ?? resolvedHeader.Description;
594-
return resolvedHeader;
589+
return Components.Headers[reference.Id];
595590

596591
case ReferenceType.SecurityScheme:
597-
var resolvedSecurityScheme = this.Components.SecuritySchemes[reference.Id];
598-
resolvedSecurityScheme.Description = reference.Description ?? resolvedSecurityScheme.Description;
599-
return resolvedSecurityScheme;
592+
return Components.SecuritySchemes[reference.Id];
600593

601594
case ReferenceType.Link:
602-
var resolvedLink = this.Components.Links[reference.Id];
603-
resolvedLink.Description = reference.Description ?? resolvedLink.Description;
604-
return resolvedLink;
595+
return Components.Links[reference.Id];
605596

606597
case ReferenceType.Callback:
607-
return this.Components.Callbacks[reference.Id];
598+
return Components.Callbacks[reference.Id];
608599

609600
default:
610601
throw new OpenApiException(Properties.SRResource.InvalidReferenceType);
@@ -716,6 +707,12 @@ public JsonSchema FindSubschema(Json.Pointer.JsonPointer pointer, EvaluationOpti
716707
{
717708
throw new NotImplementedException();
718709
}
710+
711+
internal JsonSchema ResolveJsonSchemaReference(Uri reference)
712+
{
713+
var referencePath = string.Concat("https://registry", reference.OriginalString.Split('#').Last());
714+
return (JsonSchema)SchemaRegistry.Global.Get(new Uri(referencePath));
715+
}
719716
}
720717

721718
internal class FindSchemaReferences : OpenApiVisitorBase

src/Microsoft.OpenApi/Models/OpenApiExample.cs

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Microsoft.OpenApi.Models
1313
/// <summary>
1414
/// Example Object.
1515
/// </summary>
16-
public class OpenApiExample : IOpenApiReferenceable, IOpenApiExtensible, IEffective<OpenApiExample>
16+
public class OpenApiExample : IOpenApiReferenceable, IOpenApiExtensible
1717
{
1818
/// <summary>
1919
/// Short description for the example.
@@ -101,39 +101,9 @@ internal virtual void SerializeInternal(IOpenApiWriter writer, Action<IOpenApiWr
101101
Utils.CheckArgumentNull(writer);
102102

103103
var target = this;
104-
105-
if (Reference != null)
106-
{
107-
if (!writer.GetSettings().ShouldInlineReference(Reference))
108-
{
109-
callback(writer, Reference);
110-
return;
111-
}
112-
else
113-
{
114-
target = GetEffective(Reference.HostDocument);
115-
}
116-
}
117104
action(writer, target);
118105
}
119106

120-
/// <summary>
121-
/// Returns an effective OpenApiExample object based on the presence of a $ref
122-
/// </summary>
123-
/// <param name="doc">The host OpenApiDocument that contains the reference.</param>
124-
/// <returns>OpenApiExample</returns>
125-
public OpenApiExample GetEffective(OpenApiDocument doc)
126-
{
127-
if (Reference != null)
128-
{
129-
return doc.ResolveReferenceTo<OpenApiExample>(this.Reference);
130-
}
131-
else
132-
{
133-
return this;
134-
}
135-
}
136-
137107
/// <summary>
138108
/// Serialize to OpenAPI V31 example without using reference.
139109
/// </summary>

src/Microsoft.OpenApi/Models/OpenApiHeader.cs

Lines changed: 3 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace Microsoft.OpenApi.Models
1616
/// Header Object.
1717
/// The Header Object follows the structure of the Parameter Object.
1818
/// </summary>
19-
public class OpenApiHeader : IOpenApiReferenceable, IOpenApiExtensible, IEffective<OpenApiHeader>
19+
public class OpenApiHeader : IOpenApiReferenceable, IOpenApiExtensible
2020
{
2121
private JsonSchema _schema;
2222

@@ -145,40 +145,9 @@ private void SerializeInternal(IOpenApiWriter writer, Action<IOpenApiWriter, IOp
145145
Utils.CheckArgumentNull(writer);;
146146

147147
var target = this;
148-
149-
if (Reference != null)
150-
{
151-
if (!writer.GetSettings().ShouldInlineReference(Reference))
152-
{
153-
callback(writer, Reference);
154-
return;
155-
}
156-
else
157-
{
158-
target = GetEffective(Reference.HostDocument);
159-
}
160-
}
161-
162148
action(writer, target);
163149
}
164150

165-
/// <summary>
166-
/// Returns an effective OpenApiHeader object based on the presence of a $ref
167-
/// </summary>
168-
/// <param name="doc">The host OpenApiDocument that contains the reference.</param>
169-
/// <returns>OpenApiHeader</returns>
170-
public OpenApiHeader GetEffective(OpenApiDocument doc)
171-
{
172-
if (Reference != null)
173-
{
174-
return doc.ResolveReferenceTo<OpenApiHeader>(Reference);
175-
}
176-
else
177-
{
178-
return this;
179-
}
180-
}
181-
182151
/// <summary>
183152
/// Serialize to OpenAPI V31 document without using reference.
184153
/// </summary>
@@ -244,24 +213,11 @@ internal virtual void SerializeInternalWithoutReference(IOpenApiWriter writer, O
244213
/// <summary>
245214
/// Serialize <see cref="OpenApiHeader"/> to Open Api v2.0
246215
/// </summary>
247-
public void SerializeAsV2(IOpenApiWriter writer)
216+
public virtual void SerializeAsV2(IOpenApiWriter writer)
248217
{
249-
Utils.CheckArgumentNull(writer);;
218+
Utils.CheckArgumentNull(writer);
250219

251220
var target = this;
252-
253-
if (Reference != null)
254-
{
255-
if (!writer.GetSettings().ShouldInlineReference(Reference))
256-
{
257-
Reference.SerializeAsV2(writer);
258-
return;
259-
}
260-
else
261-
{
262-
target = GetEffective(Reference.HostDocument);
263-
}
264-
}
265221
target.SerializeAsV2WithoutReference(writer);
266222
}
267223

src/Microsoft.OpenApi/Models/OpenApiLink.cs

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Microsoft.OpenApi.Models
1111
/// <summary>
1212
/// Link Object.
1313
/// </summary>
14-
public class OpenApiLink : IOpenApiReferenceable, IOpenApiExtensible, IEffective<OpenApiLink>
14+
public class OpenApiLink : IOpenApiReferenceable, IOpenApiExtensible
1515
{
1616
/// <summary>
1717
/// A relative or absolute reference to an OAS operation.
@@ -106,39 +106,9 @@ private void SerializeInternal(IOpenApiWriter writer, Action<IOpenApiWriter, IOp
106106
Utils.CheckArgumentNull(writer);
107107

108108
var target = this;
109-
110-
if (Reference != null)
111-
{
112-
if (!writer.GetSettings().ShouldInlineReference(Reference))
113-
{
114-
callback(writer, Reference);
115-
return;
116-
}
117-
else
118-
{
119-
target = GetEffective(Reference.HostDocument);
120-
}
121-
}
122109
action(writer, target);
123110
}
124111

125-
/// <summary>
126-
/// Returns an effective OpenApiLink object based on the presence of a $ref
127-
/// </summary>
128-
/// <param name="doc">The host OpenApiDocument that contains the reference.</param>
129-
/// <returns>OpenApiLink</returns>
130-
public OpenApiLink GetEffective(OpenApiDocument doc)
131-
{
132-
if (Reference != null)
133-
{
134-
return doc.ResolveReferenceTo<OpenApiLink>(Reference);
135-
}
136-
else
137-
{
138-
return this;
139-
}
140-
}
141-
142112
/// <summary>
143113
/// Serialize to OpenAPI V31 document without using reference.
144114
/// </summary>

0 commit comments

Comments
 (0)