1- // Copyright (c) Microsoft Corporation. All rights reserved.
1+ // Copyright (c) Microsoft Corporation. All rights reserved.
22// Licensed under the MIT license.
33
44using System ;
2929using Microsoft . OpenApi . Hidi . Utilities ;
3030using Microsoft . OpenApi . Models ;
3131using Microsoft . OpenApi . OData ;
32+ using Microsoft . OpenApi . Reader ;
3233using Microsoft . OpenApi . Readers ;
3334using Microsoft . OpenApi . Services ;
3435using Microsoft . OpenApi . Writers ;
@@ -38,6 +39,12 @@ namespace Microsoft.OpenApi.Hidi
3839{
3940 internal static class OpenApiService
4041 {
42+ static OpenApiService ( )
43+ {
44+ OpenApiReaderRegistry . RegisterReader ( OpenApiConstants . Yaml , new OpenApiYamlReader ( ) ) ;
45+ OpenApiReaderRegistry . RegisterReader ( OpenApiConstants . Yml , new OpenApiYamlReader ( ) ) ;
46+ }
47+
4148 /// <summary>
4249 /// Implementation of the transform command
4350 /// </summary>
@@ -52,7 +59,10 @@ public static async Task TransformOpenApiDocument(HidiOptions options, ILogger l
5259 {
5360 if ( options . Output == null )
5461 {
55- var inputExtension = GetInputPathExtension ( options . OpenApi , options . Csdl ) ;
62+ #pragma warning disable CA1308 // Normalize strings to uppercase
63+ var inputExtension = string . Concat ( "." , options . OpenApiFormat ? . GetDisplayName ( ) . ToLowerInvariant ( ) )
64+ ?? GetInputPathExtension ( options . OpenApi , options . Csdl ) ;
65+ #pragma warning restore CA1308 // Normalize strings to uppercase
5666 options . Output = new ( $ "./output{ inputExtension } ") ;
5767 } ;
5868
@@ -85,7 +95,8 @@ public static async Task TransformOpenApiDocument(HidiOptions options, ILogger l
8595 }
8696
8797 // Load OpenAPI document
88- var document = await GetOpenApi ( options , logger , options . MetadataVersion , cancellationToken ) . ConfigureAwait ( false ) ;
98+ var format = OpenApiModelFactory . GetFormat ( options . OpenApi ) ;
99+ var document = await GetOpenApi ( options , format , logger , options . MetadataVersion , cancellationToken ) . ConfigureAwait ( false ) ;
89100
90101 if ( options . FilterOptions != null )
91102 {
@@ -212,7 +223,7 @@ private static void WriteOpenApi(HidiOptions options, OpenApiFormat openApiForma
212223 }
213224
214225 // Get OpenAPI document either from OpenAPI or CSDL
215- private static async Task < OpenApiDocument > GetOpenApi ( HidiOptions options , ILogger logger , string ? metadataVersion = null , CancellationToken cancellationToken = default )
226+ private static async Task < OpenApiDocument > GetOpenApi ( HidiOptions options , string format , ILogger logger , string ? metadataVersion = null , CancellationToken cancellationToken = default )
216227 {
217228 OpenApiDocument document ;
218229 Stream stream ;
@@ -233,7 +244,7 @@ private static async Task<OpenApiDocument> GetOpenApi(HidiOptions options, ILogg
233244 await stream . DisposeAsync ( ) . ConfigureAwait ( false ) ;
234245 }
235246
236- document = await ConvertCsdlToOpenApi ( filteredStream ?? stream , metadataVersion , options . SettingsConfig , cancellationToken ) . ConfigureAwait ( false ) ;
247+ document = await ConvertCsdlToOpenApi ( filteredStream ?? stream , format , metadataVersion , options . SettingsConfig , cancellationToken ) . ConfigureAwait ( false ) ;
237248 stopwatch . Stop ( ) ;
238249 logger . LogTrace ( "{Timestamp}ms: Generated OpenAPI with {Paths} paths." , stopwatch . ElapsedMilliseconds , document . Paths . Count ) ;
239250 }
@@ -368,14 +379,16 @@ private static async Task<ReadResult> ParseOpenApi(string openApiFile, bool inli
368379 {
369380 stopwatch . Start ( ) ;
370381
371- result = await new OpenApiStreamReader ( new ( )
372- {
382+ var settings = new OpenApiReaderSettings
383+ {
373384 LoadExternalRefs = inlineExternal ,
374385 BaseUrl = openApiFile . StartsWith ( "http" , StringComparison . OrdinalIgnoreCase ) ?
375386 new ( openApiFile ) :
376387 new Uri ( "file://" + new FileInfo ( openApiFile ) . DirectoryName + Path . DirectorySeparatorChar )
377- }
378- ) . ReadAsync ( stream , cancellationToken ) . ConfigureAwait ( false ) ;
388+ } ;
389+
390+ var format = OpenApiModelFactory . GetFormat ( openApiFile ) ;
391+ result = await OpenApiDocument . LoadAsync ( stream , format , settings , cancellationToken ) . ConfigureAwait ( false ) ;
379392
380393 logger . LogTrace ( "{Timestamp}ms: Completed parsing." , stopwatch . ElapsedMilliseconds ) ;
381394
@@ -391,15 +404,15 @@ private static async Task<ReadResult> ParseOpenApi(string openApiFile, bool inli
391404 /// </summary>
392405 /// <param name="csdl">The CSDL stream.</param>
393406 /// <returns>An OpenAPI document.</returns>
394- public static async Task < OpenApiDocument > ConvertCsdlToOpenApi ( Stream csdl , string ? metadataVersion = null , IConfiguration ? settings = null , CancellationToken token = default )
407+ public static async Task < OpenApiDocument > ConvertCsdlToOpenApi ( Stream csdl , string format , string ? metadataVersion = null , IConfiguration ? settings = null , CancellationToken token = default )
395408 {
396409 using var reader = new StreamReader ( csdl ) ;
397410 var csdlText = await reader . ReadToEndAsync ( token ) . ConfigureAwait ( false ) ;
398411 var edmModel = CsdlReader . Parse ( XElement . Parse ( csdlText ) . CreateReader ( ) ) ;
399412 settings ??= SettingsUtilities . GetConfiguration ( ) ;
400413
401414 var document = edmModel . ConvertToOpenApi ( SettingsUtilities . GetOpenApiConvertSettings ( settings , metadataVersion ) ) ;
402- document = FixReferences ( document ) ;
415+ document = FixReferences ( document , format ) ;
403416
404417 return document ;
405418 }
@@ -409,14 +422,15 @@ public static async Task<OpenApiDocument> ConvertCsdlToOpenApi(Stream csdl, stri
409422 /// </summary>
410423 /// <param name="document"> The converted OpenApiDocument.</param>
411424 /// <returns> A valid OpenApiDocument instance.</returns>
412- public static OpenApiDocument FixReferences ( OpenApiDocument document )
425+ public static OpenApiDocument FixReferences ( OpenApiDocument document , string format )
413426 {
414427 // This method is only needed because the output of ConvertToOpenApi isn't quite a valid OpenApiDocument instance.
415428 // So we write it out, and read it back in again to fix it up.
416429
417430 var sb = new StringBuilder ( ) ;
418431 document . SerializeAsV3 ( new OpenApiYamlWriter ( new StringWriter ( sb ) ) ) ;
419- var doc = new OpenApiStringReader ( ) . Read ( sb . ToString ( ) , out _ ) ;
432+
433+ var doc = OpenApiDocument . Parse ( sb . ToString ( ) , format ) . OpenApiDocument ;
420434
421435 return doc ;
422436 }
@@ -564,7 +578,8 @@ private static string GetInputPathExtension(string? openapi = null, string? csdl
564578 throw new ArgumentException ( "Please input a file path or URL" ) ;
565579 }
566580
567- var document = await GetOpenApi ( options , logger , null , cancellationToken ) . ConfigureAwait ( false ) ;
581+ var format = OpenApiModelFactory . GetFormat ( options . OpenApi ) ;
582+ var document = await GetOpenApi ( options , format , logger , null , cancellationToken ) . ConfigureAwait ( false ) ;
568583
569584 using ( logger . BeginScope ( "Creating diagram" ) )
570585 {
@@ -725,7 +740,8 @@ internal static async Task PluginManifest(HidiOptions options, ILogger logger, C
725740 }
726741
727742 // Load OpenAPI document
728- var document = await GetOpenApi ( options , logger , options . MetadataVersion , cancellationToken ) . ConfigureAwait ( false ) ;
743+ var format = OpenApiModelFactory . GetFormat ( options . OpenApi ) ;
744+ var document = await GetOpenApi ( options , format , logger , options . MetadataVersion , cancellationToken ) . ConfigureAwait ( false ) ;
729745
730746 cancellationToken . ThrowIfCancellationRequested ( ) ;
731747
0 commit comments