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
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@
*/

struct IDLToStructuredSwiftTranslator: Translator {
private let typealiasTranslator = TypealiasTranslator()
private let serverCodeTranslator = ServerCodeTranslator()

func translate(
codeGenerationRequest: CodeGenerationRequest,
client: Bool,
server: Bool
) throws -> StructuredSwiftRepresentation {
let typealiasTranslator = TypealiasTranslator(client: client, server: server)
let topComment = Comment.doc(codeGenerationRequest.leadingTrivia)
let imports: [ImportDescription] = [
ImportDescription(moduleName: "GRPCCore")
]
var codeBlocks: [CodeBlock] = []
codeBlocks.append(
contentsOf: try self.typealiasTranslator.translate(from: codeGenerationRequest)
contentsOf: try typealiasTranslator.translate(from: codeGenerationRequest)
)

if server {
Expand Down
63 changes: 45 additions & 18 deletions Sources/GRPCCodeGen/Internal/Translator/TypealiasTranslator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@
/// A ``CodeGenerationRequest`` can contain multiple namespaces, so the TypealiasTranslator will create a ``CodeBlock``
/// for each namespace.
struct TypealiasTranslator: SpecializedTranslator {
let client: Bool
let server: Bool

init(client: Bool, server: Bool) {
self.client = client
self.server = server
}

func translate(from codeGenerationRequest: CodeGenerationRequest) throws -> [CodeBlock] {
var codeBlocks: [CodeBlock] = []
let services = codeGenerationRequest.services
Expand Down Expand Up @@ -169,9 +177,21 @@ extension TypealiasTranslator {
let methodDescriptorsDeclaration = self.makeMethodDescriptors(for: service)
serviceEnum.members.append(methodDescriptorsDeclaration)

// Create the streaming and non-streaming service protocol type aliases.
let serviceProtocols = self.makeServiceProtocolsTypealiases(for: service)
serviceEnum.members.append(contentsOf: serviceProtocols)
if self.server {
// Create the streaming and non-streaming service protocol type aliases.
let serviceProtocols = self.makeServiceProtocolsTypealiases(for: service)
serviceEnum.members.append(contentsOf: serviceProtocols)
}

if self.client {
// Create the client protocol type alias.
let clientProtocol = self.makeClientProtocolTypealias(for: service)
serviceEnum.members.append(clientProtocol)

// Create type alias for Client struct.
let clientStruct = self.makeClientStructTypealias(for: service)
serviceEnum.members.append(clientStruct)
}

return .enum(serviceEnum)
}
Expand Down Expand Up @@ -236,7 +256,7 @@ extension TypealiasTranslator {

let descriptorDeclarationRight = Expression.functionCall(
FunctionCallDescription(
calledExpression: .identifierType(.member(["MethodDescriptor"])),
calledExpression: .identifierType(.member("MethodDescriptor")),
arguments: [
FunctionArgumentDescription(
label: "service",
Expand Down Expand Up @@ -277,34 +297,41 @@ extension TypealiasTranslator {
isStatic: true,
kind: .let,
left: .identifier(.pattern("methods")),
type: .array(.member(["MethodDescriptor"])),
type: .array(.member("MethodDescriptor")),
right: .literal(.array(methodDescriptors))
)
}

private func makeServiceProtocolsTypealiases(
for service: CodeGenerationRequest.ServiceDescriptor
) -> [Declaration] {
let namespacedPrefix: String

if service.namespace.isEmpty {
namespacedPrefix = service.name
} else {
namespacedPrefix = "\(service.namespace)_\(service.name)"
}

let streamingServiceProtocolName = "\(namespacedPrefix)ServiceStreamingProtocol"
let streamingServiceProtocolTypealias = Declaration.typealias(
name: "StreamingServiceProtocol",
existingType: .member([streamingServiceProtocolName])
existingType: .member("\(service.namespacedPrefix)ServiceStreamingProtocol")
)

let serviceProtocolName = "\(namespacedPrefix)ServiceProtocol"
let serviceProtocolTypealias = Declaration.typealias(
name: "ServiceProtocol",
existingType: .member([serviceProtocolName])
existingType: .member("\(service.namespacedPrefix)ServiceProtocol")
)

return [streamingServiceProtocolTypealias, serviceProtocolTypealias]
}

private func makeClientProtocolTypealias(
for service: CodeGenerationRequest.ServiceDescriptor
) -> Declaration {
return .typealias(
name: "ClientProtocol",
existingType: .member("\(service.namespacedPrefix)ClientProtocol")
)
}

private func makeClientStructTypealias(
for service: CodeGenerationRequest.ServiceDescriptor
) -> Declaration {
return .typealias(
name: "Client",
existingType: .member("\(service.namespacedPrefix)Client")
)
}
}
Loading