@@ -99,7 +99,7 @@ public async Task<ReadResult> ReadAsync(JsonNode input, CancellationToken cancel
9999 {
100100 // Parse the AsyncApi Document
101101 document = this . context . Parse ( input ) ;
102- this . ResolveReferences ( diagnostic , document ) ;
102+ await this . ResolveReferencesAsync ( diagnostic , document ) ;
103103 }
104104 catch ( AsyncApiException ex )
105105 {
@@ -172,6 +172,51 @@ public T ReadFragment<T>(JsonNode input, AsyncApiVersion version, out AsyncApiDi
172172 return ( T ) element ;
173173 }
174174
175+ private async Task ResolveReferencesAsync ( AsyncApiDiagnostic diagnostic , IAsyncApiSerializable serializable )
176+ {
177+ if ( this . settings . ReferenceResolution == ReferenceResolutionSetting . DoNotResolveReferences )
178+ {
179+ return ;
180+ }
181+
182+ var collector = new AsyncApiReferenceCollector ( this . context . Workspace ) ;
183+ var walker = new AsyncApiWalker ( collector ) ;
184+ walker . Walk ( serializable ) ;
185+
186+ foreach ( var reference in collector . References )
187+ {
188+ if ( this . context . Workspace . Contains ( reference . Reference . Reference ) )
189+ {
190+ continue ;
191+ }
192+
193+ IAsyncApiSerializable component = null ;
194+ if ( reference . Reference . IsExternal )
195+ {
196+ if ( this . settings . ReferenceResolution != ReferenceResolutionSetting . ResolveAllReferences )
197+ {
198+ continue ;
199+ }
200+
201+ component = await this . ResolveExternalReferenceAsync ( diagnostic , reference ) ;
202+ }
203+ else
204+ {
205+ var stream = this . context . Workspace . ResolveReference < Stream > ( string . Empty ) ; // get whole document.
206+ component = this . ResolveStreamReference ( stream , reference , diagnostic ) ;
207+ }
208+
209+ if ( component == null )
210+ {
211+ diagnostic . Errors . Add ( new AsyncApiError ( string . Empty , $ "Unable to deserialize reference '{ reference . Reference . Reference } '") ) ;
212+ continue ;
213+ }
214+
215+ this . context . Workspace . RegisterComponent ( reference . Reference . Reference , component ) ;
216+ this . ResolveReferences ( diagnostic , component ) ;
217+ }
218+ }
219+
175220 private void ResolveReferences ( AsyncApiDiagnostic diagnostic , IAsyncApiSerializable serializable )
176221 {
177222 if ( this . settings . ReferenceResolution == ReferenceResolutionSetting . DoNotResolveReferences )
@@ -247,6 +292,36 @@ private IAsyncApiSerializable ResolveExternalReference(AsyncApiDiagnostic diagno
247292 }
248293 }
249294
295+ private async Task < IAsyncApiSerializable > ResolveExternalReferenceAsync ( AsyncApiDiagnostic diagnostic , IAsyncApiReferenceable reference )
296+ {
297+ if ( reference is null )
298+ {
299+ throw new ArgumentNullException ( nameof ( reference ) ) ;
300+ }
301+
302+ var loader = this . settings . ExternalReferenceLoader ??= new DefaultStreamLoader ( this . settings ) ;
303+ try
304+ {
305+ Stream stream ;
306+ if ( this . context . Workspace . Contains ( reference . Reference . ExternalResource ) )
307+ {
308+ stream = this . context . Workspace . ResolveReference < Stream > ( reference . Reference . ExternalResource ) ;
309+ }
310+ else
311+ {
312+ stream = await loader . LoadAsync ( new Uri ( reference . Reference . ExternalResource , UriKind . RelativeOrAbsolute ) ) ;
313+ this . context . Workspace . RegisterComponent ( reference . Reference . ExternalResource , stream ) ;
314+ }
315+
316+ return this . ResolveStreamReference ( stream , reference , diagnostic ) ;
317+ }
318+ catch ( AsyncApiException ex )
319+ {
320+ diagnostic . Errors . Add ( new AsyncApiError ( ex ) ) ;
321+ return null ;
322+ }
323+ }
324+
250325 private JsonNode ReadToJson ( Stream stream )
251326 {
252327 if ( stream != null )
0 commit comments