Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions Sources/GRPCProtobufCodeGen/ProtobufCodeGenParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,26 @@ extension ProtobufCodeGenParser {
var codeDependencies: [Dependency] = [
Dependency(module: self.moduleNames.grpcProtobuf, accessLevel: .internal)
]

// If there's a dependency on a bundled proto then add the SwiftProtobuf import.
//
// Importing SwiftProtobuf unconditionally results in warnings in the generated
// code if access-levels are used on imports and no bundled protos are used.
let dependsOnBundledProto = file.dependencies.contains { descriptor in
SwiftProtobufInfo.isBundledProto(file: descriptor)
//
// The import is only needed if a bundled proto is used as the input or output type
// for an RPC. The file may have a dependency on a bundled proto without requiring
// the SwiftProtobuf import (e.g. a message depending on a bundle proto may be
// defined in the same file as the service, the dependency will be in the '.pb.swift'
// along with the message code).
let needsProtobufImport = file.services.contains { service in
service.methods.contains { method in
let inputIsBundled = SwiftProtobufInfo.isBundledProto(file: method.inputType.file)
let outputIsBundled = SwiftProtobufInfo.isBundledProto(file: method.outputType.file)
return inputIsBundled || outputIsBundled
}
}

if dependsOnBundledProto {
if needsProtobufImport {
let dependency = Dependency(
module: self.moduleNames.swiftProtobuf,
accessLevel: self.accessLevel
Expand Down
29 changes: 21 additions & 8 deletions Sources/protoc-gen-grpc-swift-2/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ struct GeneratorOptions {
}

init(pairs: [(key: String, value: String)]) throws {
var moduleMapPath: String?

for pair in pairs {
switch pair.key {
case "Visibility":
Expand All @@ -87,14 +89,7 @@ struct GeneratorOptions {

case "ProtoPathModuleMappings":
if !pair.value.isEmpty {
do {
self.protoToModuleMappings = try ProtoFileToModuleMappings(path: pair.value)
} catch let e {
throw GenerationError.wrappedError(
message: "Parameter 'ProtoPathModuleMappings=\(pair.value)'",
error: e
)
}
moduleMapPath = pair.value
}

case "FileNaming":
Expand Down Expand Up @@ -164,6 +159,24 @@ struct GeneratorOptions {
throw GenerationError.unknownParameter(name: pair.key)
}
}

if let moduleMapPath = moduleMapPath {
do {
self.protoToModuleMappings = try ProtoFileToModuleMappings(
path: moduleMapPath,
swiftProtobufModuleName: self.config.moduleNames.swiftProtobuf
)
} catch let e {
throw GenerationError.wrappedError(
message: "Parameter 'ProtoPathModuleMappings=\(moduleMapPath)'",
error: e
)
}
} else {
self.protoToModuleMappings = ProtoFileToModuleMappings(
swiftProtobufModuleName: self.config.moduleNames.swiftProtobuf
)
}
}

static func parseParameter(string: String?) -> [(key: String, value: String)] {
Expand Down
Binary file modified Tests/GRPCProtobufCodeGenTests/Generated/test-service.pb
Binary file not shown.
35 changes: 33 additions & 2 deletions Tests/GRPCProtobufCodeGenTests/ProtobufCodeGenParserTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ struct ProtobufCodeGenParserTests {
@available(gRPCSwiftProtobuf 2.0, *)
func dependencies() throws {
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(try self.codeGen.dependencies == expected)
}
Expand Down Expand Up @@ -266,5 +265,37 @@ struct ProtobufCodeGenParserTests {
]
#expect(codeGen.dependencies == expected)
}

@Test("Generate with different module names")
@available(gRPCSwiftProtobuf 2.0, *)
func generateWithDifferentModuleNames() throws {
var config = ProtobufCodeGenerator.Config.defaults
let defaultNames = config.moduleNames

config.accessLevel = .public
config.indentation = 2
config.moduleNames.grpcCore = String(config.moduleNames.grpcCore.reversed())
config.moduleNames.grpcProtobuf = String(config.moduleNames.grpcProtobuf.reversed())
config.moduleNames.swiftProtobuf = String(config.moduleNames.swiftProtobuf.reversed())

let generator = ProtobufCodeGenerator(config: config)
let generated = try generator.generateCode(
fileDescriptor: Self.fileDescriptor,
protoFileModuleMappings: ProtoFileToModuleMappings(
swiftProtobufModuleName: config.moduleNames.swiftProtobuf
),
extraModuleImports: []
)

// Mustn't contain the default names.
#expect(!generated.contains(defaultNames.grpcCore))
#expect(!generated.contains(defaultNames.grpcProtobuf))
#expect(!generated.contains(defaultNames.swiftProtobuf))

// Must contain the configured names.
#expect(generated.contains(config.moduleNames.grpcCore))
#expect(generated.contains(config.moduleNames.grpcProtobuf))
#expect(generated.contains(config.moduleNames.swiftProtobuf))
}
}
}
30 changes: 0 additions & 30 deletions Tests/GRPCProtobufCodeGenTests/ProtobufCodeGeneratorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ struct ProtobufCodeGeneratorTests {

import GRPCCore
import GRPCProtobuf
import SwiftProtobuf

// MARK: - test.TestService

Expand Down Expand Up @@ -1103,35 +1102,6 @@ struct ProtobufCodeGeneratorTests {
#expect(generated == expected)
}

@Test("Generate with different module names")
@available(gRPCSwiftProtobuf 2.0, *)
func generateWithDifferentModuleNames() throws {
var config = ProtobufCodeGenerator.Config.defaults
let defaultNames = config.moduleNames

config.accessLevel = .public
config.indentation = 2
config.moduleNames.grpcCore = String(config.moduleNames.grpcCore.reversed())
config.moduleNames.grpcProtobuf = String(config.moduleNames.grpcProtobuf.reversed())
config.moduleNames.swiftProtobuf = String(config.moduleNames.swiftProtobuf.reversed())

let generator = ProtobufCodeGenerator(config: config)
let generated = try generator.generateCode(
fileDescriptor: Self.fileDescriptor,
protoFileModuleMappings: ProtoFileToModuleMappings(),
extraModuleImports: []
)

// Mustn't contain the default names.
#expect(!generated.contains(defaultNames.grpcCore))
#expect(!generated.contains(defaultNames.grpcProtobuf))
#expect(!generated.contains(defaultNames.swiftProtobuf))

// Must contain the configured names.
#expect(generated.contains(config.moduleNames.grpcCore))
#expect(generated.contains(config.moduleNames.grpcProtobuf))
#expect(generated.contains(config.moduleNames.swiftProtobuf))
}
}

@Suite("File-without-services (foo-messages.proto)")
Expand Down
2 changes: 1 addition & 1 deletion dev/protos/local/test-service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ syntax = "proto3";

package test;

// Using a WKT forces an "SwiftProtobuf" to be imported in generated code.
// WKT isn't used in API generated by gRPC, so no import is expected.
import "google/protobuf/any.proto";

// Service docs.
Expand Down