using Autofac; using Microsoft.CodeAnalysis; using NSwag; using Nustache.Core; #if GENERATE_AUTOMAPPER using System; using System.IO; using System.Linq; #endif using System.Collections.Generic; using System.Reflection; namespace LibKubernetesGenerator { [Generator] public class KubernetesClientSourceGenerator : IIncrementalGenerator { private static readonly object Execlock = new object(); private static (OpenApiDocument, IContainer) BuildContainer() { var swagger = OpenApiDocument.FromJsonAsync(EmbedResource.GetResource("swagger.json")).GetAwaiter().GetResult(); var container = BuildContainer(swagger); // TODO move to Handlebars.Net // here is to clean up the custom helpers in static Nustache.Core.Helpers { var ch = typeof(Helpers).GetField("CustomHelpers", BindingFlags.Static | BindingFlags.NonPublic); ((Dictionary)ch.GetValue(null)).Clear(); } foreach (var helper in container.Resolve>()) { helper.RegisterHelper(); } return (swagger, container); } private static IContainer BuildContainer(OpenApiDocument swagger) { var builder = new ContainerBuilder(); builder.RegisterType() .WithParameter(new NamedParameter(nameof(swagger), swagger)) .AsSelf() .AsImplementedInterfaces() ; builder.RegisterType() .AsImplementedInterfaces() ; builder.RegisterType() .AsImplementedInterfaces() ; builder.RegisterType() .WithParameter(new TypedParameter(typeof(OpenApiDocument), swagger)) .AsImplementedInterfaces() ; builder.RegisterType() .AsSelf() .AsImplementedInterfaces() ; builder.RegisterType() .AsSelf() .AsImplementedInterfaces() ; builder.RegisterType() .AsImplementedInterfaces() ; builder.RegisterType() .AsImplementedInterfaces() ; builder.RegisterType(); builder.RegisterType(); builder.RegisterType(); builder.RegisterType(); builder.RegisterType(); builder.RegisterType(); return builder.Build(); } public void Initialize(IncrementalGeneratorInitializationContext generatorContext) { #if GENERATE_BASIC generatorContext.RegisterPostInitializationOutput(ctx => { lock (Execlock) { var (swagger, container) = BuildContainer(); container.Resolve().Generate(swagger, ctx); container.Resolve().Generate(swagger, ctx); container.Resolve().Generate(swagger, ctx); container.Resolve().Generate(swagger, ctx); container.Resolve().Generate(swagger, ctx); } }); #endif #if GENERATE_AUTOMAPPER var automappersrc = generatorContext.CompilationProvider.Select((c, _) => c.SyntaxTrees.First(s => PathSuffixMath(s.FilePath, "AutoMapper/VersionConverter.cs"))); generatorContext.RegisterSourceOutput(automappersrc, (ctx, srctree) => { lock (Execlock) { var (swagger, container) = BuildContainer(); container.Resolve().Generate(swagger, ctx, srctree); } }); #endif } #if GENERATE_AUTOMAPPER private IEnumerable PathSplit(string path) { var p = path; while (!string.IsNullOrEmpty(p)) { yield return Path.GetFileName(p); p = Path.GetDirectoryName(p); } } private bool PathSuffixMath(string path, string suffix) { var s = PathSplit(suffix).ToList(); return PathSplit(path).Take(s.Count).SequenceEqual(s); } #endif } }