/* * DO NOT EDIT. * * Generated by the protocol buffer compiler. * Source: echo.proto * */ /* * Copyright 2018, 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 Foundation import Dispatch import gRPC import SwiftProtobuf /// Type for errors thrown from generated client code. internal enum Echo_EchoClientError : Error { case endOfStream case invalidMessageReceived case error(c: CallResult) } /// Get (Unary) internal class Echo_EchoGetCall { private var call : Call /// Create a call. fileprivate init(_ channel: Channel) { self.call = channel.makeCall("/echo.Echo/Get") } /// Run the call. Blocks until the reply is received. fileprivate func run(request: Echo_EchoRequest, metadata: Metadata) throws -> Echo_EchoResponse { let sem = DispatchSemaphore(value: 0) var returnCallResult : CallResult! var returnResponse : Echo_EchoResponse? _ = try start(request:request, metadata:metadata) {response, callResult in returnResponse = response returnCallResult = callResult sem.signal() } _ = sem.wait(timeout: DispatchTime.distantFuture) if let returnResponse = returnResponse { return returnResponse } else { throw Echo_EchoClientError.error(c: returnCallResult) } } /// Start the call. Nonblocking. fileprivate func start(request: Echo_EchoRequest, metadata: Metadata, completion: @escaping (Echo_EchoResponse?, CallResult)->()) throws -> Echo_EchoGetCall { let requestData = try request.serializedData() try call.start(.unary, metadata:metadata, message:requestData) {(callResult) in if let responseData = callResult.resultData, let response = try? Echo_EchoResponse(serializedData:responseData) { completion(response, callResult) } else { completion(nil, callResult) } } return self } /// Cancel the call. internal func cancel() { call.cancel() } } /// Expand (Server Streaming) internal class Echo_EchoExpandCall { private var call : Call /// Create a call. fileprivate init(_ channel: Channel) { self.call = channel.makeCall("/echo.Echo/Expand") } /// Call this once with the message to send. Nonblocking. fileprivate func start(request: Echo_EchoRequest, metadata: Metadata, completion: @escaping (CallResult) -> ()) throws -> Echo_EchoExpandCall { let requestData = try request.serializedData() try call.start(.serverStreaming, metadata:metadata, message:requestData, completion:completion) return self } /// Call this to wait for a result. Blocking. internal func receive() throws -> Echo_EchoResponse { var returnError : Echo_EchoClientError? var returnResponse : Echo_EchoResponse! let sem = DispatchSemaphore(value: 0) do { try receive() {response, error in returnResponse = response returnError = error sem.signal() } _ = sem.wait(timeout: DispatchTime.distantFuture) } if let returnError = returnError { throw returnError } return returnResponse } /// Call this to wait for a result. Nonblocking. internal func receive(completion:@escaping (Echo_EchoResponse?, Echo_EchoClientError?)->()) throws { do { try call.receiveMessage() {(responseData) in if let responseData = responseData { if let response = try? Echo_EchoResponse(serializedData:responseData) { completion(response, nil) } else { completion(nil, Echo_EchoClientError.invalidMessageReceived) } } else { completion(nil, Echo_EchoClientError.endOfStream) } } } } /// Cancel the call. internal func cancel() { call.cancel() } } /// Collect (Client Streaming) internal class Echo_EchoCollectCall { private var call : Call /// Create a call. fileprivate init(_ channel: Channel) { self.call = channel.makeCall("/echo.Echo/Collect") } /// Call this to start a call. Nonblocking. fileprivate func start(metadata:Metadata, completion:@escaping (CallResult)->()) throws -> Echo_EchoCollectCall { try self.call.start(.clientStreaming, metadata:metadata, completion:completion) return self } /// Call this to send each message in the request stream. Nonblocking. internal func send(_ message:Echo_EchoRequest, errorHandler:@escaping (Error)->()) throws { let messageData = try message.serializedData() try call.sendMessage(data:messageData, errorHandler:errorHandler) } /// Call this to close the connection and wait for a response. Blocking. internal func closeAndReceive() throws -> Echo_EchoResponse { var returnError : Echo_EchoClientError? var returnResponse : Echo_EchoResponse! let sem = DispatchSemaphore(value: 0) do { try closeAndReceive() {response, error in returnResponse = response returnError = error sem.signal() } _ = sem.wait(timeout: DispatchTime.distantFuture) } catch (let error) { throw error } if let returnError = returnError { throw returnError } return returnResponse } /// Call this to close the connection and wait for a response. Nonblocking. internal func closeAndReceive(completion:@escaping (Echo_EchoResponse?, Echo_EchoClientError?)->()) throws { do { try call.receiveMessage() {(responseData) in if let responseData = responseData, let response = try? Echo_EchoResponse(serializedData:responseData) { completion(response, nil) } else { completion(nil, Echo_EchoClientError.invalidMessageReceived) } } try call.close(completion:{}) } catch (let error) { throw error } } /// Cancel the call. internal func cancel() { call.cancel() } } /// Update (Bidirectional Streaming) internal class Echo_EchoUpdateCall { private var call : Call /// Create a call. fileprivate init(_ channel: Channel) { self.call = channel.makeCall("/echo.Echo/Update") } /// Call this to start a call. Nonblocking. fileprivate func start(metadata:Metadata, completion:@escaping (CallResult)->()) throws -> Echo_EchoUpdateCall { try self.call.start(.bidiStreaming, metadata:metadata, completion:completion) return self } /// Call this to wait for a result. Blocking. internal func receive() throws -> Echo_EchoResponse { var returnError : Echo_EchoClientError? var returnMessage : Echo_EchoResponse! let sem = DispatchSemaphore(value: 0) do { try receive() {response, error in returnMessage = response returnError = error sem.signal() } _ = sem.wait(timeout: DispatchTime.distantFuture) } if let returnError = returnError { throw returnError } return returnMessage } /// Call this to wait for a result. Nonblocking. internal func receive(completion:@escaping (Echo_EchoResponse?, Echo_EchoClientError?)->()) throws { do { try call.receiveMessage() {(data) in if let data = data { if let returnMessage = try? Echo_EchoResponse(serializedData:data) { completion(returnMessage, nil) } else { completion(nil, Echo_EchoClientError.invalidMessageReceived) } } else { completion(nil, Echo_EchoClientError.endOfStream) } } } } /// Call this to send each message in the request stream. internal func send(_ message:Echo_EchoRequest, errorHandler:@escaping (Error)->()) throws { let messageData = try message.serializedData() try call.sendMessage(data:messageData, errorHandler:errorHandler) } /// Call this to close the sending connection. Blocking. internal func closeSend() throws { let sem = DispatchSemaphore(value: 0) try closeSend() { sem.signal() } _ = sem.wait(timeout: DispatchTime.distantFuture) } /// Call this to close the sending connection. Nonblocking. internal func closeSend(completion:@escaping ()->()) throws { try call.close() { completion() } } /// Cancel the call. internal func cancel() { call.cancel() } } /// Call methods of this class to make API calls. internal class Echo_EchoService { public var channel: Channel /// This metadata will be sent with all requests. internal var metadata : Metadata /// This property allows the service host name to be overridden. /// For example, it can be used to make calls to "localhost:8080" /// appear to be to "example.com". internal var host : String { get { return self.channel.host } set { self.channel.host = newValue } } /// Create a client. internal init(address: String, secure: Bool = true) { gRPC.initialize() channel = Channel(address:address, secure:secure) metadata = Metadata() } /// Create a client that makes secure connections with a custom certificate and (optional) hostname. internal init(address: String, certificates: String, host: String?) { gRPC.initialize() channel = Channel(address:address, certificates:certificates, host:host) metadata = Metadata() } /// Synchronous. Unary. internal func get(_ request: Echo_EchoRequest) throws -> Echo_EchoResponse { return try Echo_EchoGetCall(channel).run(request:request, metadata:metadata) } /// Asynchronous. Unary. internal func get(_ request: Echo_EchoRequest, completion: @escaping (Echo_EchoResponse?, CallResult)->()) throws -> Echo_EchoGetCall { return try Echo_EchoGetCall(channel).start(request:request, metadata:metadata, completion:completion) } /// Asynchronous. Server-streaming. /// Send the initial message. /// Use methods on the returned object to get streamed responses. internal func expand(_ request: Echo_EchoRequest, completion: @escaping (CallResult)->()) throws -> Echo_EchoExpandCall { return try Echo_EchoExpandCall(channel).start(request:request, metadata:metadata, completion:completion) } /// Asynchronous. Client-streaming. /// Use methods on the returned object to stream messages and /// to close the connection and wait for a final response. internal func collect(completion: @escaping (CallResult)->()) throws -> Echo_EchoCollectCall { return try Echo_EchoCollectCall(channel).start(metadata:metadata, completion:completion) } /// Asynchronous. Bidirectional-streaming. /// Use methods on the returned object to stream messages, /// to wait for replies, and to close the connection. internal func update(completion: @escaping (CallResult)->()) throws -> Echo_EchoUpdateCall { return try Echo_EchoUpdateCall(channel).start(metadata:metadata, completion:completion) } } /// Type for errors thrown from generated server code. internal enum Echo_EchoServerError : Error { case endOfStream } /// To build a server, implement a class that conforms to this protocol. internal protocol Echo_EchoProvider { func get(request : Echo_EchoRequest, session : Echo_EchoGetSession) throws -> Echo_EchoResponse func expand(request : Echo_EchoRequest, session : Echo_EchoExpandSession) throws func collect(session : Echo_EchoCollectSession) throws func update(session : Echo_EchoUpdateSession) throws } /// Common properties available in each service session. internal class Echo_EchoSession { fileprivate var handler : gRPC.Handler internal var requestMetadata : Metadata { return handler.requestMetadata } internal var statusCode : Int = 0 internal var statusMessage : String = "OK" internal var initialMetadata : Metadata = Metadata() internal var trailingMetadata : Metadata = Metadata() fileprivate init(handler:gRPC.Handler) { self.handler = handler } } // Get (Unary) internal class Echo_EchoGetSession : Echo_EchoSession { private var provider : Echo_EchoProvider /// Create a session. fileprivate init(handler:gRPC.Handler, provider: Echo_EchoProvider) { self.provider = provider super.init(handler:handler) } /// Run the session. Internal. fileprivate func run(queue:DispatchQueue) throws { try handler.receiveMessage(initialMetadata:initialMetadata) {(requestData) in if let requestData = requestData { let requestMessage = try Echo_EchoRequest(serializedData:requestData) let replyMessage = try self.provider.get(request:requestMessage, session: self) try self.handler.sendResponse(message:replyMessage.serializedData(), statusCode:self.statusCode, statusMessage:self.statusMessage, trailingMetadata:self.trailingMetadata) } } } } // Expand (Server Streaming) internal class Echo_EchoExpandSession : Echo_EchoSession { private var provider : Echo_EchoProvider /// Create a session. fileprivate init(handler:gRPC.Handler, provider: Echo_EchoProvider) { self.provider = provider super.init(handler:handler) } /// Send a message. Nonblocking. internal func send(_ response: Echo_EchoResponse, completion: @escaping ()->()) throws { try handler.sendResponse(message:response.serializedData()) {completion()} } /// Run the session. Internal. fileprivate func run(queue:DispatchQueue) throws { try self.handler.receiveMessage(initialMetadata:initialMetadata) {(requestData) in if let requestData = requestData { do { let requestMessage = try Echo_EchoRequest(serializedData:requestData) // to keep providers from blocking the server thread, // we dispatch them to another queue. queue.async { do { try self.provider.expand(request:requestMessage, session: self) try self.handler.sendStatus(statusCode:self.statusCode, statusMessage:self.statusMessage, trailingMetadata:self.trailingMetadata, completion:{}) } catch (let error) { print("error: \(error)") } } } catch (let error) { print("error: \(error)") } } } } } // Collect (Client Streaming) internal class Echo_EchoCollectSession : Echo_EchoSession { private var provider : Echo_EchoProvider /// Create a session. fileprivate init(handler:gRPC.Handler, provider: Echo_EchoProvider) { self.provider = provider super.init(handler:handler) } /// Receive a message. Blocks until a message is received or the client closes the connection. internal func receive() throws -> Echo_EchoRequest { let sem = DispatchSemaphore(value: 0) var requestMessage : Echo_EchoRequest? try self.handler.receiveMessage() {(requestData) in if let requestData = requestData { requestMessage = try? Echo_EchoRequest(serializedData:requestData) } sem.signal() } _ = sem.wait(timeout: DispatchTime.distantFuture) if requestMessage == nil { throw Echo_EchoServerError.endOfStream } return requestMessage! } /// Send a response and close the connection. internal func sendAndClose(_ response: Echo_EchoResponse) throws { try self.handler.sendResponse(message:response.serializedData(), statusCode:self.statusCode, statusMessage:self.statusMessage, trailingMetadata:self.trailingMetadata) } /// Run the session. Internal. fileprivate func run(queue:DispatchQueue) throws { try self.handler.sendMetadata(initialMetadata:initialMetadata) { queue.async { do { try self.provider.collect(session:self) } catch (let error) { print("error \(error)") } } } } } // Update (Bidirectional Streaming) internal class Echo_EchoUpdateSession : Echo_EchoSession { private var provider : Echo_EchoProvider /// Create a session. fileprivate init(handler:gRPC.Handler, provider: Echo_EchoProvider) { self.provider = provider super.init(handler:handler) } /// Receive a message. Blocks until a message is received or the client closes the connection. internal func receive() throws -> Echo_EchoRequest { let sem = DispatchSemaphore(value: 0) var requestMessage : Echo_EchoRequest? try self.handler.receiveMessage() {(requestData) in if let requestData = requestData { do { requestMessage = try Echo_EchoRequest(serializedData:requestData) } catch (let error) { print("error \(error)") } } sem.signal() } _ = sem.wait(timeout: DispatchTime.distantFuture) if let requestMessage = requestMessage { return requestMessage } else { throw Echo_EchoServerError.endOfStream } } /// Send a message. Nonblocking. internal func send(_ response: Echo_EchoResponse, completion: @escaping ()->()) throws { try handler.sendResponse(message:response.serializedData()) {completion()} } /// Close a connection. Blocks until the connection is closed. internal func close() throws { let sem = DispatchSemaphore(value: 0) try self.handler.sendStatus(statusCode:self.statusCode, statusMessage:self.statusMessage, trailingMetadata:self.trailingMetadata) { sem.signal() } _ = sem.wait(timeout: DispatchTime.distantFuture) } /// Run the session. Internal. fileprivate func run(queue:DispatchQueue) throws { try self.handler.sendMetadata(initialMetadata:initialMetadata) { queue.async { do { try self.provider.update(session:self) } catch (let error) { print("error \(error)") } } } } } /// Main server for generated service internal class Echo_EchoServer { private var address: String private var server: gRPC.Server private var provider: Echo_EchoProvider? /// Create a server that accepts insecure connections. internal init(address:String, provider:Echo_EchoProvider) { gRPC.initialize() self.address = address self.provider = provider self.server = gRPC.Server(address:address) } /// Create a server that accepts secure connections. internal init?(address:String, certificateURL:URL, keyURL:URL, provider:Echo_EchoProvider) { gRPC.initialize() self.address = address self.provider = provider guard let certificate = try? String(contentsOf: certificateURL, encoding: .utf8), let key = try? String(contentsOf: keyURL, encoding: .utf8) else { return nil } self.server = gRPC.Server(address:address, key:key, certs:certificate) } /// Start the server. internal func start(queue:DispatchQueue = DispatchQueue.global()) { guard let provider = self.provider else { fatalError() // the server requires a provider } server.run {(handler) in print("Server received request to " + handler.host + " calling " + handler.method + " from " + handler.caller + " with " + String(describing:handler.requestMetadata) ) do { switch handler.method { case "/echo.Echo/Get": try Echo_EchoGetSession(handler:handler, provider:provider).run(queue:queue) case "/echo.Echo/Expand": try Echo_EchoExpandSession(handler:handler, provider:provider).run(queue:queue) case "/echo.Echo/Collect": try Echo_EchoCollectSession(handler:handler, provider:provider).run(queue:queue) case "/echo.Echo/Update": try Echo_EchoUpdateSession(handler:handler, provider:provider).run(queue:queue) default: // handle unknown requests try handler.receiveMessage(initialMetadata:Metadata()) {(requestData) in try handler.sendResponse(statusCode:12, statusMessage:"unimplemented " + handler.method, trailingMetadata:Metadata()) } } } catch (let error) { print("Server error: \(error)") } } } }