@@ -99,7 +99,7 @@ public async Task<ReadResult> ReadAsync(JsonNode input, CancellationToken cancel
99
99
{
100
100
// Parse the AsyncApi Document
101
101
document = this . context . Parse ( input ) ;
102
- this . ResolveReferences ( diagnostic , document ) ;
102
+ await this . ResolveReferencesAsync ( diagnostic , document ) ;
103
103
}
104
104
catch ( AsyncApiException ex )
105
105
{
@@ -172,6 +172,51 @@ public T ReadFragment<T>(JsonNode input, AsyncApiVersion version, out AsyncApiDi
172
172
return ( T ) element ;
173
173
}
174
174
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
+
175
220
private void ResolveReferences ( AsyncApiDiagnostic diagnostic , IAsyncApiSerializable serializable )
176
221
{
177
222
if ( this . settings . ReferenceResolution == ReferenceResolutionSetting . DoNotResolveReferences )
@@ -247,6 +292,36 @@ private IAsyncApiSerializable ResolveExternalReference(AsyncApiDiagnostic diagno
247
292
}
248
293
}
249
294
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
+
250
325
private JsonNode ReadToJson ( Stream stream )
251
326
{
252
327
if ( stream != null )
0 commit comments