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 0000000..1edf846 Binary files /dev/null and b/Tests/GRPCProtobufCodeGenTests/Generated/wkt-service.pb differ 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) {} +}