1- using Riverside . CompilerPlatform . SourceGenerators ;
2- using System . Threading ;
1+ using Riverside . CompilerPlatform . SourceGenerators ;
2+ using Riverside . CompilerPlatform . Extensions ;
3+ using Riverside . CompilerPlatform . Helpers ;
34using System ;
4- using System . Linq ;
55using System . Collections . Immutable ;
66using System . IO ;
7+ using System . Linq ;
78using System . Text ;
8- using Riverside . CompilerPlatform . Extensions ;
9- using Riverside . CompilerPlatform . Helpers ;
9+ using System . Threading ;
1010
1111namespace Riverside . CompilerPlatform . Features . Swagger ;
1212
@@ -41,78 +41,123 @@ public partial class KiotaGenerator : IncrementalGenerator
4141 /// <inheritdoc/>
4242 protected override void OnBeforeGeneration ( GeneratorContext context , CancellationToken cancellationToken )
4343 {
44- var optionsProvider = context . AnalyzerConfigOptions . GlobalOptions ;
44+ var options = context . AnalyzerConfigOptions . GlobalOptions ;
4545
46- // OpenAPI specs
4746 var specs = context . AdditionalTexts
4847 . Where ( at => at . Path . EndsWith ( ".yaml" , StringComparison . OrdinalIgnoreCase )
4948 || at . Path . EndsWith ( ".yml" , StringComparison . OrdinalIgnoreCase )
5049 || at . Path . EndsWith ( ".json" , StringComparison . OrdinalIgnoreCase ) )
5150 . ToImmutableArray ( ) ;
5251
53- optionsProvider . TryGetValue ( VersionProperty , out var version ) ;
54- optionsProvider . TryGetValue ( OptionsProperty , out var cliOptions ) ;
55- optionsProvider . TryGetValue ( LanguageProperty , out var language ) ;
56- optionsProvider . TryGetValue ( AdditionalPropertiesProperty , out var additionalProps ) ;
57-
58- version ??= string . Empty ;
59- language ??= "csharp" ;
52+ if ( specs . IsEmpty )
53+ return ;
54+
55+ var version = options . GetString ( VersionProperty ) ;
56+
57+ // Kiota engine args
58+ var language = options . GetNullableEnum < KiotaEngine . GenerationLanguage > ( LanguageProperty )
59+ ?? KiotaEngine . GenerationLanguage . CSharp ;
60+ var className = options . GetString ( ClassNameProperty ) ;
61+ var namespaceName = options . GetString ( NamespaceNameProperty ) ;
62+ var typeAccessModifier = options . GetNullableEnum < KiotaEngine . Accessibility > ( TypeAccessModifierProperty ) ;
63+ var logLevel = options . GetNullableEnum < KiotaEngine . ConsoleLogLevel > ( LogLevelProperty ) ;
64+ var backingStore = options . GetNullableBool ( BackingStoreProperty ) ;
65+ var excludeBackwardCompatible = options . GetNullableBool ( ExcludeBackwardCompatibleProperty ) ;
66+ var additionalData = options . GetNullableBool ( AdditionalDataProperty ) ;
67+ var serializers = options . GetPipeSeparatedArray ( SerializerProperty ) ;
68+ var deserializers = options . GetPipeSeparatedArray ( DeserializerProperty ) ;
69+ var cleanOutput = options . GetNullableBool ( CleanOutputProperty ) ;
70+ var structuredMimeTypes = options . GetPipeSeparatedArray ( StructuredMimeTypesProperty ) ;
71+ var includePaths = options . GetPipeSeparatedArray ( IncludePathProperty ) ;
72+ var excludePaths = options . GetPipeSeparatedArray ( ExcludePathProperty ) ;
73+ var disableValidationRules = options . GetPipeSeparatedEnumArray < KiotaEngine . ValidationRules > ( DisableValidationRulesProperty ) ;
74+ var clearCache = options . GetNullableBool ( ClearCacheProperty ) ;
75+ var disableSSLValidation = options . GetNullableBool ( DisableSSLValidationProperty ) ;
76+
77+ string toolExecutable ;
78+ try
79+ {
80+ var ( installed , installError ) = NETCoreToolHelpers
81+ . EnsureToolAsync ( "Microsoft.OpenApi.Kiota" , ToolDirectory , version )
82+ . GetAwaiter ( ) . GetResult ( ) ;
6083
61- var jarPath = EnsureToolInstallation ( version , context ) ;
84+ if ( ! installed )
85+ {
86+ CreateDiagnostic (
87+ "KG0000" ,
88+ "Kiota installation failed" ,
89+ installError ?? "Failed to install or locate the Kiota tool." ) . Report ( context ) ;
90+ return ;
91+ }
6292
63- if ( string . IsNullOrWhiteSpace ( jarPath ) )
93+ toolExecutable = NETCoreToolHelpers . GetExecutablePath ( ToolDirectory , "kiota" ) ;
94+ }
95+ catch ( Exception ex )
6496 {
65- IncrementalGenerator . CreateDiagnostic (
66- "RS0000" ,
67- "JAR not downloaded" ,
68- "An error occured whilst downloading the JAR executable to generate the OpenAPI spec" )
69- . Report ( context ) ;
97+ CreateDiagnostic ( "KG0000" , "Kiota installation failed" , ex . Message ) . Report ( context ) ;
98+ return ;
7099 }
71100
72101 foreach ( var spec in specs )
73102 {
74- try
75- {
76- var specNamespace = SanitizationHelpers . Sanitize ( Path . GetFileNameWithoutExtension ( Path . GetFileName ( spec . Path ) ) ) ;
103+ cancellationToken . ThrowIfCancellationRequested ( ) ;
77104
78- var specPath = spec . Path ;
79- if ( ! File . Exists ( specPath ) )
80- continue ;
105+ var specPath = spec . Path ;
106+ if ( ! File . Exists ( specPath ) )
107+ continue ;
81108
82- var specFileName = Path . GetFileNameWithoutExtension ( specPath ) ;
109+ var specFileName = Path . GetFileNameWithoutExtension ( specPath ) ;
110+ var effectiveNamespace = namespaceName ?? SanitizationHelpers . Sanitize ( specFileName ) ;
83111
84- var tempOut = Path . Combine ( Path . GetTempPath ( ) , "Roslyn" , "Advanced Compiler Services for .NET" , Guid . NewGuid ( ) . ToString ( "N" ) ) ;
85- Directory . CreateDirectory ( tempOut ) ;
112+ var tempOut = DirectoryHelpers . CreateTemporary (
113+ Path . Combine ( Path . GetTempPath ( ) , "Roslyn" , "Advanced Compiler Services for .NET" ) ) ;
86114
87- if ( ! string . IsNullOrWhiteSpace ( cliOptions ) )
88- {
89- argsBuilder . Append ( " " ) ;
90- argsBuilder . Append ( cliOptions ) ;
91- }
92-
93- if ( ! string . IsNullOrWhiteSpace ( additionalProps ) )
94- {
95- argsBuilder . Append ( " --additional-properties=" ) ;
96- argsBuilder . Append ( SanitizationHelpers . EscapeArg ( additionalProps ! ) ) ;
97- }
98-
99- var args = argsBuilder . ToString ( ) ;
100-
101- var runResult = ProcessHelpers . RunProcess ( "java" , args , TimeSpan . FromMinutes ( 2 ) ) . GetAwaiter ( ) . GetResult ( ) ;
115+ try
116+ {
117+ var engine = new KiotaEngine (
118+ d : specPath ,
119+ a : null ,
120+ o : tempOut ,
121+ l : language ,
122+ c : className ,
123+ n : effectiveNamespace ,
124+ tam : typeAccessModifier ,
125+ ll : logLevel ,
126+ b : backingStore ,
127+ ebc : excludeBackwardCompatible ,
128+ ad : additionalData ,
129+ s : serializers ,
130+ ds : deserializers ,
131+ co : cleanOutput ,
132+ m : structuredMimeTypes ,
133+ i : includePaths ,
134+ e : excludePaths ,
135+ dvr : disableValidationRules ,
136+ cc : clearCache ,
137+ dsv : disableSSLValidation ) ;
138+
139+ var runResult = ProcessHelpers
140+ . RunProcess ( toolExecutable , engine . ToString ( ) , TimeSpan . FromMinutes ( 2 ) )
141+ . GetAwaiter ( ) . GetResult ( ) ;
102142
103143 if ( runResult . ExitCode != 0 )
104144 {
105- CreateDiagnostic ( "RS0000" , "OpenAPI generator failed" , $ "OpenAPI generator failed for spec '{ spec . Path } ' with exit code { runResult . ExitCode } : { runResult . StandardError . ReplaceLineEndings ( " " ) } ") . Report ( context ) ;
106- TryDeleteDirectory ( tempOut ) ;
145+ CreateDiagnostic (
146+ "KG0001" ,
147+ "Kiota generation failed" ,
148+ $ "Kiota failed for spec '{ specPath } ' with exit code { runResult . ExitCode } : { runResult . StandardError . ReplaceLineEndings ( " " ) } ") . Report ( context ) ;
149+ DirectoryHelpers . TryDelete ( tempOut ) ;
107150 continue ;
108151 }
109152
110- var srcDir = Path . Combine ( tempOut , "src" , specNamespace ) ;
111- var csFiles = Directory . EnumerateFiles ( srcDir , "*.cs" , SearchOption . AllDirectories ) . ToArray ( ) ;
153+ var csFiles = Directory . EnumerateFiles ( tempOut , "*.cs" , SearchOption . AllDirectories ) . ToArray ( ) ;
112154 if ( csFiles . Length == 0 )
113155 {
114- CreateDiagnostic ( "RS0000" , "No C# files generated" , $ "OpenAPI generator produced no C# files for spec '{ spec . Path } '") . Report ( context ) ;
115- TryDeleteDirectory ( tempOut ) ;
156+ CreateDiagnostic (
157+ "KG0002" ,
158+ "No C# files generated" ,
159+ $ "Kiota produced no C# files for spec '{ specPath } '") . Report ( context ) ;
160+ DirectoryHelpers . TryDelete ( tempOut ) ;
116161 continue ;
117162 }
118163
@@ -122,52 +167,27 @@ protected override void OnBeforeGeneration(GeneratorContext context, Cancellatio
122167 {
123168 var content = File . ReadAllText ( cs , Encoding . UTF8 ) ;
124169 var rel = Path . GetRelativePath ( tempOut , cs )
125- . Replace ( Path . DirectorySeparatorChar , '_' )
126- . Replace ( Path . AltDirectorySeparatorChar , '_' ) ;
127-
128- var hintName = $ "{ SanitizationHelpers . Sanitize ( specFileName ) } _{ SanitizationHelpers . Sanitize ( rel ) } ";
170+ . Replace ( Path . DirectorySeparatorChar , '.' )
171+ . Replace ( Path . AltDirectorySeparatorChar , '.' ) ;
172+ var hintName = $ "{ SanitizationHelpers . Sanitize ( engine . NamespaceName ! ) } .{ SanitizationHelpers . Sanitize ( rel ) } ";
129173 AddSource ( hintName , content ) ;
130174 }
131175 catch ( Exception ex )
132176 {
133- CreateDiagnostic ( "RS0000" , "Failed to add generated file" , $ "Failed to add generated file '{ cs } ': { ex . Message } ") . Report ( context ) ;
177+ CreateDiagnostic (
178+ "KG0003" ,
179+ "Failed to add generated file" ,
180+ $ "Failed to add '{ cs } ': { ex . Message } ") . Report ( context ) ;
134181 }
135182 }
136183
137- TryDeleteDirectory ( tempOut ) ;
138-
139- AddSource ( $ "{ SanitizationHelpers . Sanitize ( specFileName ) } _AnyOf", AnyOf_Polyfill ( specNamespace + ".Model" ) ) ;
184+ //DirectoryHelpers.TryDelete(tempOut);
140185 }
141186 catch ( Exception ex )
142187 {
143- CreateDiagnostic ( "RS9999" , "OpenAPI generator exception" , ex . ToString ( ) ) ;
188+ CreateDiagnostic ( "KG9999" , "Kiota generator exception" , ex . ToString ( ) ) . Report ( context ) ;
189+ DirectoryHelpers . TryDelete ( tempOut ) ;
144190 }
145191 }
146192 }
147-
148- private static string ? EnsureToolInstallation ( string version , GeneratorContext context )
149- {
150- try
151- {
152- var baseDir = Path . Combine ( Path . GetTempPath ( ) , "Roslyn" , "Advanced Compiler Services for .NET" , "KiotaGenerator" ) ;
153- Directory . CreateDirectory ( baseDir ) ;
154-
155- var jarPath = Path . Combine ( baseDir , $ "openapi-generator-cli-{ version } .jar") ;
156- if ( File . Exists ( jarPath ) )
157- return jarPath ;
158-
159- return jarPath ;
160- }
161- catch ( Exception ex )
162- {
163- CreateDiagnostic ( "RS0000" , $ "Failed to download OpenAPI generator JAR", $ "Could not download version { version } : { ex . Message } ") . Report ( context ) ;
164- return null ;
165- }
166- }
167-
168- private static void TryDeleteDirectory ( string path )
169- {
170- try { if ( Directory . Exists ( path ) ) Directory . Delete ( path , true ) ; }
171- catch { }
172- }
173193}
0 commit comments