Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ let products: [Product] = [
let dependencies: [Package.Dependency] = [
.package(
url: "https://github.com/grpc/grpc-swift.git",
from: "2.0.0"
branch: "main"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is temporary so that CI runs, we'll need bump to a version containing grpc/grpc-swift#2201 once it's released.

),
.package(
url: "https://github.com/apple/swift-protobuf.git",
Expand Down
17 changes: 12 additions & 5 deletions Sources/GRPCProtobufCodeGen/ProtobufCodeGenParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,18 @@ package struct ProtobufCodeGenParser {
let extraModuleImports: [String]
let protoToModuleMappings: ProtoFileToModuleMappings
let accessLevel: CodeGenerator.Config.AccessLevel
let moduleNames: ProtobufCodeGenerator.Config.ModuleNames

package init(
protoFileModuleMappings: ProtoFileToModuleMappings,
extraModuleImports: [String],
accessLevel: CodeGenerator.Config.AccessLevel
accessLevel: CodeGenerator.Config.AccessLevel,
moduleNames: ProtobufCodeGenerator.Config.ModuleNames
) {
self.extraModuleImports = extraModuleImports
self.protoToModuleMappings = protoFileModuleMappings
self.accessLevel = accessLevel
self.moduleNames = moduleNames
}

package func parse(descriptor: FileDescriptor) throws -> CodeGenerationRequest {
Expand Down Expand Up @@ -86,10 +89,10 @@ package struct ProtobufCodeGenParser {
dependencies: self.codeDependencies(file: descriptor),
services: services,
makeSerializerCodeSnippet: { messageType in
"GRPCProtobuf.ProtobufSerializer<\(messageType)>()"
"\(self.moduleNames.grpcProtobuf).ProtobufSerializer<\(messageType)>()"
},
makeDeserializerCodeSnippet: { messageType in
"GRPCProtobuf.ProtobufDeserializer<\(messageType)>()"
"\(self.moduleNames.grpcProtobuf).ProtobufDeserializer<\(messageType)>()"
}
)
}
Expand All @@ -102,7 +105,7 @@ extension ProtobufCodeGenParser {
}

var codeDependencies: [Dependency] = [
Dependency(module: "GRPCProtobuf", accessLevel: .internal)
Dependency(module: self.moduleNames.grpcProtobuf, accessLevel: .internal)
]
// If there's a dependency on a bundled proto then add the SwiftProtobuf import.
//
Expand All @@ -113,7 +116,11 @@ extension ProtobufCodeGenParser {
}

if dependsOnBundledProto {
codeDependencies.append(Dependency(module: "SwiftProtobuf", accessLevel: self.accessLevel))
let dependency = Dependency(
module: self.moduleNames.swiftProtobuf,
accessLevel: self.accessLevel
)
codeDependencies.append(dependency)
}

// Adding as dependencies the modules containing generated code or types for
Expand Down
54 changes: 50 additions & 4 deletions Sources/GRPCProtobufCodeGen/ProtobufCodeGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ package import GRPCCodeGen
package import SwiftProtobufPluginLibrary

package struct ProtobufCodeGenerator {
internal var config: GRPCCodeGen.CodeGenerator.Config
internal var config: ProtobufCodeGenerator.Config

package init(
config: GRPCCodeGen.CodeGenerator.Config
config: ProtobufCodeGenerator.Config
) {
self.config = config
}
Expand All @@ -34,12 +34,58 @@ package struct ProtobufCodeGenerator {
let parser = ProtobufCodeGenParser(
protoFileModuleMappings: protoFileModuleMappings,
extraModuleImports: extraModuleImports,
accessLevel: self.config.accessLevel
accessLevel: self.config.accessLevel,
moduleNames: self.config.moduleNames
)
let codeGenerator = GRPCCodeGen.CodeGenerator(config: self.config)

var codeGeneratorConfig = GRPCCodeGen.CodeGenerator.Config(
accessLevel: self.config.accessLevel,
accessLevelOnImports: self.config.accessLevelOnImports,
client: self.config.generateClient,
server: self.config.generateServer,
indentation: self.config.indentation
)
codeGeneratorConfig.grpcCoreModuleName = self.config.moduleNames.grpcCore
let codeGenerator = GRPCCodeGen.CodeGenerator(config: codeGeneratorConfig)

let codeGenerationRequest = try parser.parse(descriptor: fileDescriptor)
let sourceFile = try codeGenerator.generate(codeGenerationRequest)
return sourceFile.contents
}
}

extension ProtobufCodeGenerator {
package struct Config {
package var accessLevel: GRPCCodeGen.CodeGenerator.Config.AccessLevel
package var accessLevelOnImports: Bool

package var generateClient: Bool
package var generateServer: Bool

package var indentation: Int
package var moduleNames: ModuleNames

package struct ModuleNames {
package var grpcCore: String
package var grpcProtobuf: String
package var swiftProtobuf: String

package static let defaults = Self(
grpcCore: "GRPCCore",
grpcProtobuf: "GRPCProtobuf",
swiftProtobuf: "SwiftProtobuf"
)
}

package static var defaults: Self {
Self(
accessLevel: .internal,
accessLevelOnImports: false,
generateClient: true,
generateServer: true,
indentation: 4,
moduleNames: .defaults
)
}
}
}
24 changes: 1 addition & 23 deletions Sources/protoc-gen-grpc-swift/GenerateGRPC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ final class GenerateGRPC: SwiftProtobufPluginLibrary.CodeGenerator {
fileNamingOption: options.fileNaming
)

let config = CodeGenerator.Config(options: options)
let fileGenerator = ProtobufCodeGenerator(config: config)
let fileGenerator = ProtobufCodeGenerator(config: options.config)
let contents = try fileGenerator.generateCode(
fileDescriptor: descriptor,
protoFileModuleMappings: options.protoToModuleMappings,
Expand Down Expand Up @@ -181,24 +180,3 @@ private func splitPath(pathname: String) -> (dir: String, base: String, suffix:
}
return (dir: dir, base: base, suffix: suffix)
}

extension GRPCCodeGen.CodeGenerator.Config {
init(options: GeneratorOptions) {
let accessLevel: GRPCCodeGen.CodeGenerator.Config.AccessLevel
switch options.visibility {
case .internal:
accessLevel = .internal
case .package:
accessLevel = .package
case .public:
accessLevel = .public
}

self.init(
accessLevel: accessLevel,
accessLevelOnImports: options.useAccessLevelOnImports,
client: options.generateClient,
server: options.generateServer
)
}
}
66 changes: 34 additions & 32 deletions Sources/protoc-gen-grpc-swift/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* limitations under the License.
*/

import GRPCCodeGen
import GRPCProtobufCodeGen
import SwiftProtobufPluginLibrary

enum GenerationError: Error, CustomStringConvertible {
Expand Down Expand Up @@ -43,35 +45,13 @@ enum FileNaming: String {
}

struct GeneratorOptions {
enum Visibility: String {
case `internal` = "Internal"
case `public` = "Public"
case `package` = "Package"

var sourceSnippet: String {
switch self {
case .internal:
return "internal"
case .public:
return "public"
case .package:
return "package"
}
}
}

private(set) var visibility = Visibility.internal

private(set) var generateServer = true
private(set) var generateClient = true

private(set) var protoToModuleMappings = ProtoFileToModuleMappings()
private(set) var fileNaming = FileNaming.fullPath
private(set) var extraModuleImports: [String] = []
private(set) var gRPCModuleName = "GRPC"
private(set) var swiftProtobufModuleName = "SwiftProtobuf"

private(set) var generateReflectionData = false
private(set) var useAccessLevelOnImports = false

private(set) var config: ProtobufCodeGenerator.Config = .defaults

init(parameter: any CodeGeneratorParameter) throws {
try self.init(pairs: parameter.parsedPairs)
Expand All @@ -81,22 +61,22 @@ struct GeneratorOptions {
for pair in pairs {
switch pair.key {
case "Visibility":
if let value = Visibility(rawValue: pair.value) {
self.visibility = value
if let value = GRPCCodeGen.CodeGenerator.Config.AccessLevel(protocOption: pair.value) {
self.config.accessLevel = value
} else {
throw GenerationError.invalidParameterValue(name: pair.key, value: pair.value)
}

case "Server":
if let value = Bool(pair.value.lowercased()) {
self.generateServer = value
self.config.generateServer = value
} else {
throw GenerationError.invalidParameterValue(name: pair.key, value: pair.value)
}

case "Client":
if let value = Bool(pair.value.lowercased()) {
self.generateClient = value
self.config.generateClient = value
} else {
throw GenerationError.invalidParameterValue(name: pair.key, value: pair.value)
}
Expand Down Expand Up @@ -129,14 +109,21 @@ struct GeneratorOptions {

case "GRPCModuleName":
if !pair.value.isEmpty {
self.gRPCModuleName = pair.value
self.config.moduleNames.grpcCore = pair.value
} else {
throw GenerationError.invalidParameterValue(name: pair.key, value: pair.value)
}

case "GRPCProtobufModuleName":
if !pair.value.isEmpty {
self.config.moduleNames.grpcProtobuf = pair.value
} else {
throw GenerationError.invalidParameterValue(name: pair.key, value: pair.value)
}

case "SwiftProtobufModuleName":
if !pair.value.isEmpty {
self.swiftProtobufModuleName = pair.value
self.config.moduleNames.swiftProtobuf = pair.value
} else {
throw GenerationError.invalidParameterValue(name: pair.key, value: pair.value)
}
Expand All @@ -150,7 +137,7 @@ struct GeneratorOptions {

case "UseAccessLevelOnImports":
if let value = Bool(pair.value.lowercased()) {
self.useAccessLevelOnImports = value
self.config.accessLevelOnImports = value
} else {
throw GenerationError.invalidParameterValue(name: pair.key, value: pair.value)
}
Expand Down Expand Up @@ -194,3 +181,18 @@ extension String.SubSequence {
return String(trimmed)
}
}

extension GRPCCodeGen.CodeGenerator.Config.AccessLevel {
fileprivate init?(protocOption value: String) {
switch value {
case "Internal":
self = .internal
case "Public":
self = .public
case "Package":
self = .package
default:
return nil
}
}
}
Binary file modified Tests/GRPCProtobufCodeGenTests/Generated/test-service.pb
Binary file not shown.
56 changes: 38 additions & 18 deletions Tests/GRPCProtobufCodeGenTests/ProtobufCodeGeneratorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,10 @@ struct ProtobufCodeGeneratorTests {

@Test("Generate", arguments: [CodeGenerator.Config.AccessLevel.internal])
func generate(accessLevel: GRPCCodeGen.CodeGenerator.Config.AccessLevel) throws {
let generator = ProtobufCodeGenerator(
config: CodeGenerator.Config(
accessLevel: accessLevel,
accessLevelOnImports: false,
client: true,
server: true,
indentation: 2
)
)
var config = ProtobufCodeGenerator.Config.defaults
config.accessLevel = accessLevel
config.indentation = 2
let generator = ProtobufCodeGenerator(config: config)

let access: String
switch accessLevel {
Expand Down Expand Up @@ -1062,6 +1057,35 @@ struct ProtobufCodeGeneratorTests {

#expect(generated == expected)
}

@Test("Generate with different module names")
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 All @@ -1071,15 +1095,11 @@ struct ProtobufCodeGeneratorTests {

@Test("Generate")
func generate() throws {
let generator = ProtobufCodeGenerator(
config: CodeGenerator.Config(
accessLevel: .public,
accessLevelOnImports: false,
client: true,
server: true,
indentation: 2
)
)
var config: ProtobufCodeGenerator.Config = .defaults
config.accessLevel = .public
config.indentation = 2

let generator = ProtobufCodeGenerator(config: config)

let generated = try generator.generateCode(
fileDescriptor: Self.fileDescriptor,
Expand Down
3 changes: 2 additions & 1 deletion Tests/GRPCProtobufCodeGenTests/Utilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ func parseDescriptor(
let parser = ProtobufCodeGenParser(
protoFileModuleMappings: .init(),
extraModuleImports: extraModuleImports,
accessLevel: accessLevel
accessLevel: accessLevel,
moduleNames: .defaults
)
return try parser.parse(descriptor: descriptor)
}
4 changes: 3 additions & 1 deletion dev/protos/generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ function generate_test_service_descriptor_set {
proto_path="$(dirname "$proto")"
output="$root/Tests/GRPCProtobufCodeGenTests/Generated/test-service.pb"

invoke_protoc --descriptor_set_out="$output" "$proto" -I "$proto_path" --include_source_info
invoke_protoc --descriptor_set_out="$output" "$proto" -I "$proto_path" \
--include_imports \
--include_source_info
}

function generate_foo_service_descriptor_set {
Expand Down
Loading
Loading