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
2 changes: 1 addition & 1 deletion Sources/Examples/Echo/Model/echo.grpc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ extension Echo_EchoProvider {
}


/// Provides conformance to `GRPCPayload` for the request and response messages
// Provides conformance to `GRPCPayload` for request and response messages
extension Echo_EchoRequest: GRPCProtobufPayload {}
extension Echo_EchoResponse: GRPCProtobufPayload {}

2 changes: 1 addition & 1 deletion Sources/Examples/HelloWorld/Model/helloworld.grpc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ extension Helloworld_GreeterProvider {
}


/// Provides conformance to `GRPCPayload` for the request and response messages
// Provides conformance to `GRPCPayload` for request and response messages
extension Helloworld_HelloRequest: GRPCProtobufPayload {}
extension Helloworld_HelloReply: GRPCProtobufPayload {}

2 changes: 1 addition & 1 deletion Sources/Examples/RouteGuide/Model/route_guide.grpc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ extension Routeguide_RouteGuideProvider {
}


/// Provides conformance to `GRPCPayload` for the request and response messages
// Provides conformance to `GRPCPayload` for request and response messages
extension Routeguide_Point: GRPCProtobufPayload {}
extension Routeguide_Feature: GRPCProtobufPayload {}
extension Routeguide_Rectangle: GRPCProtobufPayload {}
Expand Down
40 changes: 40 additions & 0 deletions Sources/protoc-gen-grpc-swift/Generator-Conformance.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2020, gRPC Authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import SwiftProtobuf
import SwiftProtobufPluginLibrary

extension Generator {
internal func printProtobufExtensions() {
println("// Provides conformance to `GRPCPayload` for request and response messages")
for service in self.file.services {
self.service = service
for method in self.service.methods {
self.method = method
self.printExtension(for: self.methodInputName)
self.printExtension(for: self.methodOutputName)
}
println()
}
}

private func printExtension(for messageType: String) {
guard !self.observedMessages.contains(messageType) else {
return
}
self.println("extension \(messageType): GRPCProtobufPayload {}")
self.observedMessages.insert(messageType)
}
}
27 changes: 5 additions & 22 deletions Sources/protoc-gen-grpc-swift/Generator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ class Generator {
internal var service: ServiceDescriptor! // context during generation
internal var method: MethodDescriptor! // context during generation

internal var observedMessages: Set<String>
internal let protobufNamer: SwiftProtobufNamer

init(_ file: FileDescriptor, options: GeneratorOptions) {
init(_ file: FileDescriptor, options: GeneratorOptions, observedMessages: Set<String>) {
self.file = file
self.options = options
self.observedMessages = observedMessages
self.printer = CodePrinter()
self.protobufNamer = SwiftProtobufNamer(
currentFile: file,
Expand Down Expand Up @@ -117,27 +119,8 @@ class Generator {
printServer()
}
}
println()
printProtoBufExtensions()
}

internal func printProtoBufExtensions() {
var writtenValues = Set<String>()
println("/// Provides conformance to `GRPCPayload` for the request and response messages")
for service in file.services {
self.service = service
for method in service.methods {
self.method = method
printExtension(for: methodInputName, typesSeen: &writtenValues)
printExtension(for: methodOutputName, typesSeen: &writtenValues)
}
println()
}
self.println()
self.printProtobufExtensions()
}

private func printExtension(for messageType: String, typesSeen: inout Set<String>) {
guard !typesSeen.contains(messageType) else { return }
println("extension \(messageType): GRPCProtobufPayload {}")
typesSeen.insert(messageType)
}
}
13 changes: 9 additions & 4 deletions Sources/protoc-gen-grpc-swift/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ func uniqueOutputFileName(component: String, fileDescriptor: FileDescriptor, fil
}

func main() throws {

// initialize responses
var response = Google_Protobuf_Compiler_CodeGeneratorResponse()

Expand All @@ -103,15 +102,21 @@ func main() throws {
// Build the SwiftProtobufPluginLibrary model of the plugin input
let descriptorSet = DescriptorSet(protos: request.protoFile)

// process each .proto file separately
for fileDescriptor in descriptorSet.files {
// We need to generate conformance to `GRPCPayload` for request/response types. Track which
// types we've seen to avoid generating the conformance multiple times.
var observedMessages = Set<String>()

// process each .proto file in filename order in an attempt to stabilise the output (i.e. where
// conformance to `GRPCPayload` is generated)
for fileDescriptor in descriptorSet.files.sorted(by: { $0.name < $1.name }) {
if fileDescriptor.services.count > 0 {
let grpcFileName = uniqueOutputFileName(component: "grpc", fileDescriptor: fileDescriptor, fileNamingOption: options.fileNaming)
let grpcGenerator = Generator(fileDescriptor, options: options)
let grpcGenerator = Generator(fileDescriptor, options: options, observedMessages: observedMessages)
var grpcFile = Google_Protobuf_Compiler_CodeGeneratorResponse.File()
grpcFile.name = grpcFileName
grpcFile.content = grpcGenerator.code
response.file.append(grpcFile)
observedMessages.formUnion(grpcGenerator.observedMessages)
}
}

Expand Down