Skip to content

Commit

Permalink
Generated reflection service code
Browse files Browse the repository at this point in the history
Motivation:

In order to develop the Reflection Service, the specific proto file should be included in the module and
the service code generated from it.

Modifications:

Created the module for the Reflection Service, added the proto file, updated the Package.swift
to include the module, updated the Makefile to inlude targets for generating the server code,
created the ReflectionProvider.

Result:

The Reflection Service can now be implemented.
  • Loading branch information
stefanadranca committed Oct 3, 2023
1 parent 09c46b0 commit c739a06
Show file tree
Hide file tree
Showing 6 changed files with 1,163 additions and 1 deletion.
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,22 @@ ${SERIALIZATION_GRPC_REFLECTION}: ${ECHO_PROTO} ${PROTOC_GEN_GRPC_SWIFT}
.PHONY:
generate-reflection-data: ${SERIALIZATION_GRPC_REFLECTION}

REFLECTION_PROTO=Sources/GRPCReflectionService/Model/reflection.proto
REFLECTION_PB=$(REFLECTION_PROTO:.proto=.pb.swift)
REFLECTION_GRPC=$(REFLECTION_PROTO:.proto=.grpc.swift)

# For Reflection we'll generate only the Server code.
${REFLECTION_GRPC}: ${REFLECTION_PROTO} ${PROTOC_GEN_GRPC_SWIFT}
protoc $< \
--proto_path=$(dir $<) \
--plugin=${PROTOC_GEN_GRPC_SWIFT} \
--grpc-swift_opt=Client=false \
--grpc-swift_out=$(dir $<)

# Generates protobufs and gRPC server for the Reflection Service
.PHONY:
generate-reflection: ${REFLECTION_PB} ${REFLECTION_GRPC}

### Testing ####################################################################

# Normal test suite.
Expand Down
17 changes: 16 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ extension Target.Dependency {
static let interopTestModels: Self = .target(name: "GRPCInteroperabilityTestModels")
static let interopTestImplementation: Self =
.target(name: "GRPCInteroperabilityTestsImplementation")

static let reflectionService: Self = .target(name: "ReflectionService")

// Product dependencies
static let argumentParser: Self = .product(
name: "ArgumentParser",
Expand Down Expand Up @@ -428,6 +429,19 @@ extension Target {
"README.md",
]
)

static let reflectionService: Target = .target(
name: "ReflectionService",
dependencies: [
.grpc,
.nio,
.protobuf,
],
path: "Sources/GRPCReflectionService",
exclude: [
"Model/reflection.proto",
]
)
}

// MARK: - Products
Expand Down Expand Up @@ -471,6 +485,7 @@ let package = Package(
.cgrpcZlib,
.protocGenGRPCSwift,
.grpcSwiftPlugin,
.reflectionService,

// Tests etc.
.grpcTests,
Expand Down
122 changes: 122 additions & 0 deletions Sources/GRPCReflectionService/Model/reflection.grpc.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
//
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the protocol buffer compiler.
// Source: reflection.proto
//
import GRPC
import NIO
import NIOConcurrencyHelpers
import SwiftProtobuf


/// To build a server, implement a class that conforms to this protocol.
internal protocol Reflection_ServerReflectionProvider: CallHandlerProvider {
var interceptors: Reflection_ServerReflectionServerInterceptorFactoryProtocol? { get }

/// The reflection service is structured as a bidirectional stream, ensuring
/// all related requests go to a single server.
func serverReflectionInfo(context: StreamingResponseCallContext<Reflection_ServerReflectionResponse>) -> EventLoopFuture<(StreamEvent<Reflection_ServerReflectionRequest>) -> Void>
}

extension Reflection_ServerReflectionProvider {
internal var serviceName: Substring {
return Reflection_ServerReflectionServerMetadata.serviceDescriptor.fullName[...]
}

/// Determines, calls and returns the appropriate request handler, depending on the request's method.
/// Returns nil for methods not handled by this service.
internal func handle(
method name: Substring,
context: CallHandlerContext
) -> GRPCServerHandlerProtocol? {
switch name {
case "ServerReflectionInfo":
return BidirectionalStreamingServerHandler(
context: context,
requestDeserializer: ProtobufDeserializer<Reflection_ServerReflectionRequest>(),
responseSerializer: ProtobufSerializer<Reflection_ServerReflectionResponse>(),
interceptors: self.interceptors?.makeServerReflectionInfoInterceptors() ?? [],
observerFactory: self.serverReflectionInfo(context:)
)

default:
return nil
}
}
}

/// To implement a server, implement an object which conforms to this protocol.
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
internal protocol Reflection_ServerReflectionAsyncProvider: CallHandlerProvider, Sendable {
static var serviceDescriptor: GRPCServiceDescriptor { get }
var interceptors: Reflection_ServerReflectionServerInterceptorFactoryProtocol? { get }

/// The reflection service is structured as a bidirectional stream, ensuring
/// all related requests go to a single server.
func serverReflectionInfo(
requestStream: GRPCAsyncRequestStream<Reflection_ServerReflectionRequest>,
responseStream: GRPCAsyncResponseStreamWriter<Reflection_ServerReflectionResponse>,
context: GRPCAsyncServerCallContext
) async throws
}

@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
extension Reflection_ServerReflectionAsyncProvider {
internal static var serviceDescriptor: GRPCServiceDescriptor {
return Reflection_ServerReflectionServerMetadata.serviceDescriptor
}

internal var serviceName: Substring {
return Reflection_ServerReflectionServerMetadata.serviceDescriptor.fullName[...]
}

internal var interceptors: Reflection_ServerReflectionServerInterceptorFactoryProtocol? {
return nil
}

internal func handle(
method name: Substring,
context: CallHandlerContext
) -> GRPCServerHandlerProtocol? {
switch name {
case "ServerReflectionInfo":
return GRPCAsyncServerHandler(
context: context,
requestDeserializer: ProtobufDeserializer<Reflection_ServerReflectionRequest>(),
responseSerializer: ProtobufSerializer<Reflection_ServerReflectionResponse>(),
interceptors: self.interceptors?.makeServerReflectionInfoInterceptors() ?? [],
wrapping: { try await self.serverReflectionInfo(requestStream: $0, responseStream: $1, context: $2) }
)

default:
return nil
}
}
}

internal protocol Reflection_ServerReflectionServerInterceptorFactoryProtocol: Sendable {

/// - Returns: Interceptors to use when handling 'serverReflectionInfo'.
/// Defaults to calling `self.makeInterceptors()`.
func makeServerReflectionInfoInterceptors() -> [ServerInterceptor<Reflection_ServerReflectionRequest, Reflection_ServerReflectionResponse>]
}

internal enum Reflection_ServerReflectionServerMetadata {
internal static let serviceDescriptor = GRPCServiceDescriptor(
name: "ServerReflection",
fullName: "reflection.ServerReflection",
methods: [
Reflection_ServerReflectionServerMetadata.Methods.serverReflectionInfo,
]
)

internal enum Methods {
internal static let serverReflectionInfo = GRPCMethodDescriptor(
name: "ServerReflectionInfo",
path: "/reflection.ServerReflection/ServerReflectionInfo",
type: GRPCCallType.bidirectionalStreaming
)
}
}
Loading

0 comments on commit c739a06

Please sign in to comment.