From 97dfddeb460fe1188c0dcaac1469e3b913df17be Mon Sep 17 00:00:00 2001 From: George Barnett Date: Thu, 5 Dec 2024 10:28:25 +0000 Subject: [PATCH] Only generate SwiftProtobuf import for well-known types (#17) Motivation: In (#16) an import for SwiftProtobuf was added to account for well-known types. However, if no well-known types are used then warnings are emitted when the access level is included on the import. Modifications: - Only generate the SwiftProtobuf import for well-known types Result: Fewer warnings --- .../ProtobufCodeGenParser.swift | 18 +++++++++-- .../Generated/wkt-service.pb | Bin 0 -> 6232 bytes .../ProtobufCodeGenParserTests.swift | 28 +++++++++++++++--- .../ProtobufCodeGeneratorTests.swift | 1 - dev/protos/generate.sh | 12 ++++++++ dev/protos/local/wkt-service.proto | 10 +++++++ 6 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 Tests/GRPCProtobufCodeGenTests/Generated/wkt-service.pb create mode 100644 dev/protos/local/wkt-service.proto diff --git a/Sources/GRPCProtobufCodeGen/ProtobufCodeGenParser.swift b/Sources/GRPCProtobufCodeGen/ProtobufCodeGenParser.swift index 69a48da..c4ca5b0 100644 --- a/Sources/GRPCProtobufCodeGen/ProtobufCodeGenParser.swift +++ b/Sources/GRPCProtobufCodeGen/ProtobufCodeGenParser.swift @@ -96,9 +96,23 @@ extension ProtobufCodeGenParser { file: FileDescriptor ) -> [Dependency] { var codeDependencies: [Dependency] = [ - Dependency(module: "GRPCProtobuf", accessLevel: .internal), - Dependency(module: "SwiftProtobuf", accessLevel: self.accessLevel), + Dependency(module: "GRPCProtobuf", accessLevel: .internal) ] + + // If any services in the file depend on well-known Protobuf types then also import + // SwiftProtobuf. Importing SwiftProtobuf unconditionally results in warnings in the generated + // code if access-levels are used on imports and no well-known types are used. + let usesAnyWellKnownTypesInServices = file.services.contains { service in + service.methods.contains { method in + let inputIsWellKnown = method.inputType.wellKnownType != nil + let outputIsWellKnown = method.outputType.wellKnownType != nil + return inputIsWellKnown || outputIsWellKnown + } + } + if usesAnyWellKnownTypesInServices { + codeDependencies.append(Dependency(module: "SwiftProtobuf", accessLevel: self.accessLevel)) + } + // Adding as dependencies the modules containing generated code or types for // '.proto' files imported in the '.proto' file we are parsing. codeDependencies.append( diff --git a/Tests/GRPCProtobufCodeGenTests/Generated/wkt-service.pb b/Tests/GRPCProtobufCodeGenTests/Generated/wkt-service.pb new file mode 100644 index 0000000000000000000000000000000000000000..1edf846aa1d48ed3a0747b336790c75163f66a18 GIT binary patch literal 6232 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 q-qAo44~f(AxUWoB3M_Z`GgY3i&rUbZx=_ literal 0 HcmV?d00001 diff --git a/Tests/GRPCProtobufCodeGenTests/ProtobufCodeGenParserTests.swift b/Tests/GRPCProtobufCodeGenTests/ProtobufCodeGenParserTests.swift index 60610f3..f86273b 100644 --- a/Tests/GRPCProtobufCodeGenTests/ProtobufCodeGenParserTests.swift +++ b/Tests/GRPCProtobufCodeGenTests/ProtobufCodeGenParserTests.swift @@ -61,8 +61,7 @@ struct ProtobufCodeGenParserTests { @Test("Dependencies") func dependencies() { let expected: [GRPCCodeGen.Dependency] = [ - .init(module: "GRPCProtobuf", accessLevel: .internal), // Always an internal import - .init(module: "SwiftProtobuf", accessLevel: .internal), + .init(module: "GRPCProtobuf", accessLevel: .internal) // Always an internal import ] #expect(self.codeGen.dependencies == expected) } @@ -174,8 +173,7 @@ struct ProtobufCodeGenParserTests { @Test("Dependencies") func dependencies() { let expected: [GRPCCodeGen.Dependency] = [ - .init(module: "GRPCProtobuf", accessLevel: .internal), // Always an internal import - .init(module: "SwiftProtobuf", accessLevel: .internal), + .init(module: "GRPCProtobuf", accessLevel: .internal) // Always an internal import ] #expect(self.codeGen.dependencies == expected) } @@ -237,4 +235,26 @@ struct ProtobufCodeGenParserTests { #expect(self.service.namespace.base == "") } } + + @Suite("Service using 'well-known types' (wkt-service.proto)") + struct WKTService: UsesDescriptorSet { + static let descriptorSetName = "wkt-service" + static let fileDescriptorName = "wkt-service" + + let codeGen: CodeGenerationRequest + + init() throws { + let descriptor = try #require(try Self.fileDescriptor) + self.codeGen = try parseDescriptor(descriptor) + } + + @Test("Dependencies") + func dependencies() { + let expected: [Dependency] = [ + Dependency(module: "GRPCProtobuf", accessLevel: .internal), + Dependency(module: "SwiftProtobuf", accessLevel: .internal), + ] + #expect(self.codeGen.dependencies == expected) + } + } } diff --git a/Tests/GRPCProtobufCodeGenTests/ProtobufCodeGeneratorTests.swift b/Tests/GRPCProtobufCodeGenTests/ProtobufCodeGeneratorTests.swift index ddbd9ef..6422b96 100644 --- a/Tests/GRPCProtobufCodeGenTests/ProtobufCodeGeneratorTests.swift +++ b/Tests/GRPCProtobufCodeGenTests/ProtobufCodeGeneratorTests.swift @@ -67,7 +67,6 @@ struct ProtobufCodeGeneratorTests: UsesDescriptorSet { import GRPCCore import GRPCProtobuf - import SwiftProtobuf // MARK: - test.TestService diff --git a/dev/protos/generate.sh b/dev/protos/generate.sh index 8f87099..2faa25d 100755 --- a/dev/protos/generate.sh +++ b/dev/protos/generate.sh @@ -59,9 +59,21 @@ function generate_bar_service_descriptor_set { --include_imports } +function generate_wkt_service_descriptor_set { + local proto proto_path output + proto="$here/local/wkt-service.proto" + proto_path="$(dirname "$proto")" + output="$root/Tests/GRPCProtobufCodeGenTests/Generated/wkt-service.pb" + + invoke_protoc --descriptor_set_out="$output" "$proto" -I "$proto_path" \ + --include_source_info \ + --include_imports +} + #------------------------------------------------------------------------------ # Descriptor sets generate_test_service_descriptor_set generate_foo_service_descriptor_set generate_bar_service_descriptor_set +generate_wkt_service_descriptor_set diff --git a/dev/protos/local/wkt-service.proto b/dev/protos/local/wkt-service.proto new file mode 100644 index 0000000..d9beb94 --- /dev/null +++ b/dev/protos/local/wkt-service.proto @@ -0,0 +1,10 @@ +// Leading trivia. +syntax = "proto3"; + +package test; + +import "google/protobuf/any.proto"; + +service WKTService { + rpc Method (google.protobuf.Any) returns (google.protobuf.Any) {} +}