diff --git a/Google.Api.Generator/CodeGenerator.cs b/Google.Api.Generator/CodeGenerator.cs index 0a46a106..15b70a0f 100644 --- a/Google.Api.Generator/CodeGenerator.cs +++ b/Google.Api.Generator/CodeGenerator.cs @@ -86,11 +86,11 @@ internal static class CodeGenerator new Regex(@"^System\.?.*", RegexOptions.Compiled | RegexOptions.CultureInvariant), }; - private static readonly IReadOnlyList AllowedAdditionalServices = new List + private static readonly IReadOnlyList AllowedAdditionalServices = new List { - IAMPolicy.Descriptor.FullName, - Locations.Descriptor.FullName, - Operations.Descriptor.FullName, + IAMPolicy.Descriptor, + Locations.Descriptor, + Operations.Descriptor, }.AsReadOnly(); public static IEnumerable Generate(FileDescriptorSet descriptorSet, string package, IClock clock, @@ -121,6 +121,7 @@ public static IEnumerable Generate(IReadOnlyList(); + var resultFilesByProtoPackage = new Dictionary>(); foreach (var singlePackageFileDescs in byPackage) { // Find the right library settings by matching the proto package we're publishing. @@ -134,15 +135,22 @@ public static IEnumerable Generate(IReadOnlyList(); foreach (var resultFile in GeneratePackage( namespaces[0], singlePackageFileDescs, catalog, clock, grpcServiceConfig, serviceConfig, allServiceDetails, transports, requestNumericEnumJsonEncoding, librarySettings)) { - yield return resultFile; + files.Add(resultFile); + } + if (files.Count > 0) + { + resultFilesByProtoPackage[singlePackageFileDescs.Key] = files; } } + var resultFiles = GetResultFilesToCreate(resultFilesByProtoPackage); + // We assume that the first service we've generated corresponds to the service config (if we have one), // and is a service from the primary library we're generating. This is used for API validation and // gapic_metadata.json generation. This means it doesn't matter (for gapic_metadata.json) @@ -155,12 +163,12 @@ public static IEnumerable Generate(IReadOnlyList api.Name) ?? Enumerable.Empty()) .Except(primaryLibraryServices.Select(s => s.ServiceFullName)) - .Except(AllowedAdditionalServices) + .Except(AllowedAdditionalServices.Select(s => s.FullName)) .ToList(); if (unhandledApis.Any()) @@ -169,6 +177,29 @@ public static IEnumerable Generate(IReadOnlyList GetResultFilesToCreate(Dictionary> filesByProtoPackage) + { + var mixinPackages = AllowedAdditionalServices.Select(svc => svc.File.Package).ToHashSet(); + + // Unless we're *only* generating mixins, remove all mixins. + if (!filesByProtoPackage.Keys.All(mixinPackages.Contains)) + { + foreach (var pkg in mixinPackages) + { + filesByProtoPackage.Remove(pkg); + } + } + + // We may still have multiple packages here, and that's probably not + // ideal, but it's not too bad - and it deals with the common situation. + return filesByProtoPackage.Values.SelectMany(list => list).ToList(); + } } private static void ValidateTransports(ApiTransports transports, List services)