@@ -16,8 +16,8 @@ public class OpenApiWorkspace
1616 private readonly Dictionary < string , Uri > _documentsIdRegistry = new ( ) ;
1717 private readonly Dictionary < Uri , Stream > _artifactsRegistry = new ( ) ;
1818 private readonly Dictionary < Uri , IOpenApiReferenceable > _IOpenApiReferenceableRegistry = new ( new UriWithFragmentEqualityComparer ( ) ) ;
19- private readonly Dictionary < OpenApiDocument , Dictionary < string , List < IOpenApiSchema > > > _dynamicAnchorRegistryByDocument = new ( ) ;
20- private readonly Dictionary < OpenApiDocument , Dictionary < string , List < IOpenApiSchema > > > _anchorRegistryByDocument = new ( ) ;
19+ private Dictionary < OpenApiDocument , Dictionary < string , List < IOpenApiSchema > > > ? _dynamicAnchorRegistryByDocument ;
20+ private Dictionary < OpenApiDocument , Dictionary < string , List < IOpenApiSchema > > > ? _anchorRegistryByDocument ;
2121
2222 private sealed class UriWithFragmentEqualityComparer : IEqualityComparer < Uri >
2323 {
@@ -280,6 +280,7 @@ private void RegisterInlineAnchors(OpenApiDocument document)
280280 // shared `visited` set, mirroring RegisterAnchorsRecursive's schema-cycle guard.
281281 private void RegisterPathItemAnchors ( OpenApiDocument document , IOpenApiPathItem pathItem , HashSet < object > visited )
282282 {
283+ if ( pathItem is OpenApiPathItemReference ) return ;
283284 if ( ! visited . Add ( pathItem ) ) return ;
284285
285286 if ( pathItem . Parameters is not null )
@@ -293,6 +294,7 @@ private void RegisterPathItemAnchors(OpenApiDocument document, IOpenApiPathItem
293294
294295 private void RegisterCallbackAnchors ( OpenApiDocument document , IOpenApiCallback callback , HashSet < object > visited )
295296 {
297+ if ( callback is OpenApiCallbackReference ) return ;
296298 if ( ! visited . Add ( callback ) ) return ;
297299
298300 if ( callback . PathItems is not null )
@@ -322,16 +324,21 @@ private void RegisterOperationAnchors(OpenApiDocument document, OpenApiOperation
322324
323325 private void RegisterParameterAnchors ( OpenApiDocument document , IOpenApiParameter parameter )
324326 {
327+ if ( parameter is OpenApiParameterReference ) return ;
325328 if ( parameter . Schema is not null )
326329 RegisterAnchors ( document , parameter . Schema ) ;
327330 RegisterMediaTypeSchemas ( document , parameter . Content ) ;
328331 }
329332
330333 private void RegisterRequestBodyAnchors ( OpenApiDocument document , IOpenApiRequestBody requestBody )
331- => RegisterMediaTypeSchemas ( document , requestBody . Content ) ;
334+ {
335+ if ( requestBody is OpenApiRequestBodyReference ) return ;
336+ RegisterMediaTypeSchemas ( document , requestBody . Content ) ;
337+ }
332338
333339 private void RegisterResponseAnchors ( OpenApiDocument document , IOpenApiResponse response )
334340 {
341+ if ( response is OpenApiResponseReference ) return ;
335342 RegisterMediaTypeSchemas ( document , response . Content ) ;
336343 if ( response . Headers is not null )
337344 foreach ( var header in response . Headers . Values . Where ( h => h is not null ) )
@@ -340,6 +347,7 @@ private void RegisterResponseAnchors(OpenApiDocument document, IOpenApiResponse
340347
341348 private void RegisterHeaderAnchors ( OpenApiDocument document , IOpenApiHeader header )
342349 {
350+ if ( header is OpenApiHeaderReference ) return ;
343351 if ( header . Schema is not null )
344352 RegisterAnchors ( document , header . Schema ) ;
345353 RegisterMediaTypeSchemas ( document , header . Content ) ;
@@ -348,7 +356,7 @@ private void RegisterHeaderAnchors(OpenApiDocument document, IOpenApiHeader head
348356 private void RegisterMediaTypeSchemas ( OpenApiDocument document , IDictionary < string , IOpenApiMediaType > ? content )
349357 {
350358 if ( content is null ) return ;
351- foreach ( var mediaType in content . Values . Where ( m => m is not null ) )
359+ foreach ( var mediaType in content . Values . Where ( m => m is not null and not OpenApiMediaTypeReference ) )
352360 {
353361 if ( mediaType . Schema is not null )
354362 RegisterAnchors ( document , mediaType . Schema ) ;
@@ -546,7 +554,8 @@ private static IEnumerable<IOpenApiSchema> EnumerateMissingPropertiesChildren(IO
546554
547555 private void RegisterAnchor ( OpenApiDocument document , string anchorName , IOpenApiSchema schema , bool isDynamic )
548556 {
549- var registry = isDynamic ? _dynamicAnchorRegistryByDocument : _anchorRegistryByDocument ;
557+ ref var registry = ref ( isDynamic ? ref _dynamicAnchorRegistryByDocument : ref _anchorRegistryByDocument ) ;
558+ registry ??= new ( ) ;
550559 if ( ! registry . TryGetValue ( document , out var anchors ) )
551560 {
552561 anchors = new ( StringComparer . Ordinal ) ;
@@ -568,7 +577,8 @@ private void RegisterAnchor(OpenApiDocument document, string anchorName, IOpenAp
568577 /// </summary>
569578 internal IOpenApiSchema ? ResolveAnchor ( OpenApiDocument hostDocument , string anchorName )
570579 {
571- if ( _anchorRegistryByDocument . TryGetValue ( hostDocument , out var anchors ) &&
580+ if ( _anchorRegistryByDocument is not null &&
581+ _anchorRegistryByDocument . TryGetValue ( hostDocument , out var anchors ) &&
572582 anchors . TryGetValue ( anchorName , out var candidates ) )
573583 return candidates . Count == 1 ? candidates [ 0 ] : null ;
574584 return null ;
@@ -580,11 +590,14 @@ private void RegisterAnchor(OpenApiDocument document, string anchorName, IOpenAp
580590 /// </summary>
581591 internal OpenApiDocument ? FindDocumentByBaseUri ( string documentUri )
582592 {
583- return _dynamicAnchorRegistryByDocument . Keys
584- . Concat ( _anchorRegistryByDocument . Keys )
585- . Distinct ( )
586- . FirstOrDefault ( doc => doc . BaseUri is not null
587- && doc . BaseUri . ToString ( ) . Equals ( documentUri , StringComparison . OrdinalIgnoreCase ) ) ;
593+ if ( ! Uri . TryCreate ( documentUri , UriKind . Absolute , out var uri ) ) return null ;
594+ if ( _dynamicAnchorRegistryByDocument is not null )
595+ foreach ( var doc in _dynamicAnchorRegistryByDocument . Keys )
596+ if ( doc . BaseUri == uri ) return doc ;
597+ if ( _anchorRegistryByDocument is not null )
598+ foreach ( var doc in _anchorRegistryByDocument . Keys )
599+ if ( doc . BaseUri == uri ) return doc ;
600+ return null ;
588601 }
589602
590603 /// <summary>
@@ -599,7 +612,8 @@ private void RegisterAnchor(OpenApiDocument document, string anchorName, IOpenAp
599612 /// <returns>All candidate schemas, or an empty list if none.</returns>
600613 public IReadOnlyList < IOpenApiSchema > GetDynamicAnchorCandidates ( OpenApiDocument hostDocument , string anchorName )
601614 {
602- if ( _dynamicAnchorRegistryByDocument . TryGetValue ( hostDocument , out var anchors ) &&
615+ if ( _dynamicAnchorRegistryByDocument is not null &&
616+ _dynamicAnchorRegistryByDocument . TryGetValue ( hostDocument , out var anchors ) &&
603617 anchors . TryGetValue ( anchorName , out var candidates ) )
604618 return candidates . AsReadOnly ( ) ;
605619 return [ ] ;
0 commit comments