diff --git a/.licenseignore b/.licenseignore index d1c5126..7b0e633 100644 --- a/.licenseignore +++ b/.licenseignore @@ -39,3 +39,4 @@ dev/version-bump.commit.template LICENSE **/*.swift dev/protos/**/*.proto +**/*.pb diff --git a/Sources/GRPCReflectionService/Generated/reflection.grpc.swift b/Sources/GRPCReflectionService/Generated/reflection.grpc.swift new file mode 100644 index 0000000..cfa79c9 --- /dev/null +++ b/Sources/GRPCReflectionService/Generated/reflection.grpc.swift @@ -0,0 +1,346 @@ +// Copyright 2016 The gRPC Authors +// +// 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. + +// Service exported by server reflection. A more complete description of how +// server reflection works can be found at +// https://github.com/grpc/grpc/blob/master/doc/server-reflection.md +// +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto + +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the gRPC Swift generator plugin for the protocol buffer compiler. +// Source: reflection.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/grpc/grpc-swift + +package import GRPCCore +internal import GRPCProtobuf + +// MARK: - grpc.reflection.v1.ServerReflection + +/// Namespace containing generated types for the "grpc.reflection.v1.ServerReflection" service. +package enum Grpc_Reflection_V1_ServerReflection { + /// Service descriptor for the "grpc.reflection.v1.ServerReflection" service. + package static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "grpc.reflection.v1.ServerReflection") + /// Namespace for method metadata. + package enum Method { + /// Namespace for "ServerReflectionInfo" metadata. + package enum ServerReflectionInfo { + /// Request type for "ServerReflectionInfo". + package typealias Input = Grpc_Reflection_V1_ServerReflectionRequest + /// Response type for "ServerReflectionInfo". + package typealias Output = Grpc_Reflection_V1_ServerReflectionResponse + /// Descriptor for "ServerReflectionInfo". + package static let descriptor = GRPCCore.MethodDescriptor( + service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "grpc.reflection.v1.ServerReflection"), + method: "ServerReflectionInfo" + ) + } + /// Descriptors for all methods in the "grpc.reflection.v1.ServerReflection" service. + package static let descriptors: [GRPCCore.MethodDescriptor] = [ + ServerReflectionInfo.descriptor + ] + } +} + +extension GRPCCore.ServiceDescriptor { + /// Service descriptor for the "grpc.reflection.v1.ServerReflection" service. + package static let grpc_reflection_v1_ServerReflection = GRPCCore.ServiceDescriptor(fullyQualifiedService: "grpc.reflection.v1.ServerReflection") +} + +// MARK: grpc.reflection.v1.ServerReflection (server) + +extension Grpc_Reflection_V1_ServerReflection { + /// Streaming variant of the service protocol for the "grpc.reflection.v1.ServerReflection" service. + /// + /// This protocol is the lowest-level of the service protocols generated for this service + /// giving you the most flexibility over the implementation of your service. This comes at + /// the cost of more verbose and less strict APIs. Each RPC requires you to implement it in + /// terms of a request stream and response stream. Where only a single request or response + /// message is expected, you are responsible for enforcing this invariant is maintained. + /// + /// Where possible, prefer using the stricter, less-verbose ``ServiceProtocol`` + /// or ``SimpleServiceProtocol`` instead. + package protocol StreamingServiceProtocol: GRPCCore.RegistrableRPCService { + /// Handle the "ServerReflectionInfo" method. + /// + /// > Source IDL Documentation: + /// > + /// > The reflection service is structured as a bidirectional stream, ensuring + /// > all related requests go to a single server. + /// + /// - Parameters: + /// - request: A streaming request of `Grpc_Reflection_V1_ServerReflectionRequest` messages. + /// - context: Context providing information about the RPC. + /// - Throws: Any error which occurred during the processing of the request. Thrown errors + /// of type `RPCError` are mapped to appropriate statuses. All other errors are converted + /// to an internal error. + /// - Returns: A streaming response of `Grpc_Reflection_V1_ServerReflectionResponse` messages. + func serverReflectionInfo( + request: GRPCCore.StreamingServerRequest, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse + } + + /// Service protocol for the "grpc.reflection.v1.ServerReflection" service. + /// + /// This protocol is higher level than ``StreamingServiceProtocol`` but lower level than + /// the ``SimpleServiceProtocol``, it provides access to request and response metadata and + /// trailing response metadata. If you don't need these then consider using + /// the ``SimpleServiceProtocol``. If you need fine grained control over your RPCs then + /// use ``StreamingServiceProtocol``. + package protocol ServiceProtocol: Grpc_Reflection_V1_ServerReflection.StreamingServiceProtocol { + /// Handle the "ServerReflectionInfo" method. + /// + /// > Source IDL Documentation: + /// > + /// > The reflection service is structured as a bidirectional stream, ensuring + /// > all related requests go to a single server. + /// + /// - Parameters: + /// - request: A streaming request of `Grpc_Reflection_V1_ServerReflectionRequest` messages. + /// - context: Context providing information about the RPC. + /// - Throws: Any error which occurred during the processing of the request. Thrown errors + /// of type `RPCError` are mapped to appropriate statuses. All other errors are converted + /// to an internal error. + /// - Returns: A streaming response of `Grpc_Reflection_V1_ServerReflectionResponse` messages. + func serverReflectionInfo( + request: GRPCCore.StreamingServerRequest, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse + } + + /// Simple service protocol for the "grpc.reflection.v1.ServerReflection" service. + /// + /// This is the highest level protocol for the service. The API is the easiest to use but + /// doesn't provide access to request or response metadata. If you need access to these + /// then use ``ServiceProtocol`` instead. + package protocol SimpleServiceProtocol: Grpc_Reflection_V1_ServerReflection.ServiceProtocol { + /// Handle the "ServerReflectionInfo" method. + /// + /// > Source IDL Documentation: + /// > + /// > The reflection service is structured as a bidirectional stream, ensuring + /// > all related requests go to a single server. + /// + /// - Parameters: + /// - request: A stream of `Grpc_Reflection_V1_ServerReflectionRequest` messages. + /// - response: A response stream of `Grpc_Reflection_V1_ServerReflectionResponse` messages. + /// - context: Context providing information about the RPC. + /// - Throws: Any error which occurred during the processing of the request. Thrown errors + /// of type `RPCError` are mapped to appropriate statuses. All other errors are converted + /// to an internal error. + func serverReflectionInfo( + request: GRPCCore.RPCAsyncSequence, + response: GRPCCore.RPCWriter, + context: GRPCCore.ServerContext + ) async throws + } +} + +// Default implementation of 'registerMethods(with:)'. +extension Grpc_Reflection_V1_ServerReflection.StreamingServiceProtocol { + package func registerMethods(with router: inout GRPCCore.RPCRouter) { + router.registerHandler( + forMethod: Grpc_Reflection_V1_ServerReflection.Method.ServerReflectionInfo.descriptor, + deserializer: GRPCProtobuf.ProtobufDeserializer(), + serializer: GRPCProtobuf.ProtobufSerializer(), + handler: { request, context in + try await self.serverReflectionInfo( + request: request, + context: context + ) + } + ) + } +} + +// Default implementation of streaming methods from 'StreamingServiceProtocol'. +extension Grpc_Reflection_V1_ServerReflection.ServiceProtocol { +} + +// Default implementation of methods from 'ServiceProtocol'. +extension Grpc_Reflection_V1_ServerReflection.SimpleServiceProtocol { + package func serverReflectionInfo( + request: GRPCCore.StreamingServerRequest, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse { + return GRPCCore.StreamingServerResponse( + metadata: [:], + producer: { writer in + try await self.serverReflectionInfo( + request: request.messages, + response: writer, + context: context + ) + return [:] + } + ) + } +} + +// MARK: grpc.reflection.v1.ServerReflection (client) + +extension Grpc_Reflection_V1_ServerReflection { + /// Generated client protocol for the "grpc.reflection.v1.ServerReflection" service. + /// + /// You don't need to implement this protocol directly, use the generated + /// implementation, ``Client``. + package protocol ClientProtocol: Sendable { + /// Call the "ServerReflectionInfo" method. + /// + /// > Source IDL Documentation: + /// > + /// > The reflection service is structured as a bidirectional stream, ensuring + /// > all related requests go to a single server. + /// + /// - Parameters: + /// - request: A streaming request producing `Grpc_Reflection_V1_ServerReflectionRequest` messages. + /// - serializer: A serializer for `Grpc_Reflection_V1_ServerReflectionRequest` messages. + /// - deserializer: A deserializer for `Grpc_Reflection_V1_ServerReflectionResponse` messages. + /// - options: Options to apply to this RPC. + /// - handleResponse: A closure which handles the response, the result of which is + /// returned to the caller. Returning from the closure will cancel the RPC if it + /// hasn't already finished. + /// - Returns: The result of `handleResponse`. + func serverReflectionInfo( + request: GRPCCore.StreamingClientRequest, + serializer: some GRPCCore.MessageSerializer, + deserializer: some GRPCCore.MessageDeserializer, + options: GRPCCore.CallOptions, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result + ) async throws -> Result where Result: Sendable + } + + /// Generated client for the "grpc.reflection.v1.ServerReflection" service. + /// + /// The ``Client`` provides an implementation of ``ClientProtocol`` which wraps + /// a `GRPCCore.GRPCCClient`. The underlying `GRPCClient` provides the long-lived + /// means of communication with the remote peer. + package struct Client: ClientProtocol { + private let client: GRPCCore.GRPCClient + + /// Creates a new client wrapping the provided `GRPCCore.GRPCClient`. + /// + /// - Parameters: + /// - client: A `GRPCCore.GRPCClient` providing a communication channel to the service. + package init(wrapping client: GRPCCore.GRPCClient) { + self.client = client + } + + /// Call the "ServerReflectionInfo" method. + /// + /// > Source IDL Documentation: + /// > + /// > The reflection service is structured as a bidirectional stream, ensuring + /// > all related requests go to a single server. + /// + /// - Parameters: + /// - request: A streaming request producing `Grpc_Reflection_V1_ServerReflectionRequest` messages. + /// - serializer: A serializer for `Grpc_Reflection_V1_ServerReflectionRequest` messages. + /// - deserializer: A deserializer for `Grpc_Reflection_V1_ServerReflectionResponse` messages. + /// - options: Options to apply to this RPC. + /// - handleResponse: A closure which handles the response, the result of which is + /// returned to the caller. Returning from the closure will cancel the RPC if it + /// hasn't already finished. + /// - Returns: The result of `handleResponse`. + package func serverReflectionInfo( + request: GRPCCore.StreamingClientRequest, + serializer: some GRPCCore.MessageSerializer, + deserializer: some GRPCCore.MessageDeserializer, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result + ) async throws -> Result where Result: Sendable { + try await self.client.bidirectionalStreaming( + request: request, + descriptor: Grpc_Reflection_V1_ServerReflection.Method.ServerReflectionInfo.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + onResponse: handleResponse + ) + } + } +} + +// Helpers providing default arguments to 'ClientProtocol' methods. +extension Grpc_Reflection_V1_ServerReflection.ClientProtocol { + /// Call the "ServerReflectionInfo" method. + /// + /// > Source IDL Documentation: + /// > + /// > The reflection service is structured as a bidirectional stream, ensuring + /// > all related requests go to a single server. + /// + /// - Parameters: + /// - request: A streaming request producing `Grpc_Reflection_V1_ServerReflectionRequest` messages. + /// - options: Options to apply to this RPC. + /// - handleResponse: A closure which handles the response, the result of which is + /// returned to the caller. Returning from the closure will cancel the RPC if it + /// hasn't already finished. + /// - Returns: The result of `handleResponse`. + package func serverReflectionInfo( + request: GRPCCore.StreamingClientRequest, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result + ) async throws -> Result where Result: Sendable { + try await self.serverReflectionInfo( + request: request, + serializer: GRPCProtobuf.ProtobufSerializer(), + deserializer: GRPCProtobuf.ProtobufDeserializer(), + options: options, + onResponse: handleResponse + ) + } +} + +// Helpers providing sugared APIs for 'ClientProtocol' methods. +extension Grpc_Reflection_V1_ServerReflection.ClientProtocol { + /// Call the "ServerReflectionInfo" method. + /// + /// > Source IDL Documentation: + /// > + /// > The reflection service is structured as a bidirectional stream, ensuring + /// > all related requests go to a single server. + /// + /// - Parameters: + /// - metadata: Additional metadata to send, defaults to empty. + /// - options: Options to apply to this RPC, defaults to `.defaults`. + /// - producer: A closure producing request messages to send to the server. The request + /// stream is closed when the closure returns. + /// - handleResponse: A closure which handles the response, the result of which is + /// returned to the caller. Returning from the closure will cancel the RPC if it + /// hasn't already finished. + /// - Returns: The result of `handleResponse`. + package func serverReflectionInfo( + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter) async throws -> Void, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.StreamingClientRequest( + metadata: metadata, + producer: producer + ) + return try await self.serverReflectionInfo( + request: request, + options: options, + onResponse: handleResponse + ) + } +} \ No newline at end of file diff --git a/Sources/GRPCReflectionService/Generated/reflection.pb.swift b/Sources/GRPCReflectionService/Generated/reflection.pb.swift new file mode 100644 index 0000000..533cd5e --- /dev/null +++ b/Sources/GRPCReflectionService/Generated/reflection.pb.swift @@ -0,0 +1,775 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// swiftlint:disable all +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: reflection.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Copyright 2016 The gRPC Authors +// +// 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. + +// Service exported by server reflection. A more complete description of how +// server reflection works can be found at +// https://github.com/grpc/grpc/blob/master/doc/server-reflection.md +// +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto + +package import Foundation +package import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// The message sent by the client when calling ServerReflectionInfo method. +package struct Grpc_Reflection_V1_ServerReflectionRequest: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + package var host: String = String() + + /// To use reflection service, the client should set one of the following + /// fields in message_request. The server distinguishes requests by their + /// defined field and then handles them using corresponding methods. + package var messageRequest: Grpc_Reflection_V1_ServerReflectionRequest.OneOf_MessageRequest? = nil + + /// Find a proto file by the file name. + package var fileByFilename: String { + get { + if case .fileByFilename(let v)? = messageRequest {return v} + return String() + } + set {messageRequest = .fileByFilename(newValue)} + } + + /// Find the proto file that declares the given fully-qualified symbol name. + /// This field should be a fully-qualified symbol name + /// (e.g. .[.] or .). + package var fileContainingSymbol: String { + get { + if case .fileContainingSymbol(let v)? = messageRequest {return v} + return String() + } + set {messageRequest = .fileContainingSymbol(newValue)} + } + + /// Find the proto file which defines an extension extending the given + /// message type with the given field number. + package var fileContainingExtension: Grpc_Reflection_V1_ExtensionRequest { + get { + if case .fileContainingExtension(let v)? = messageRequest {return v} + return Grpc_Reflection_V1_ExtensionRequest() + } + set {messageRequest = .fileContainingExtension(newValue)} + } + + /// Finds the tag numbers used by all known extensions of the given message + /// type, and appends them to ExtensionNumberResponse in an undefined order. + /// Its corresponding method is best-effort: it's not guaranteed that the + /// reflection service will implement this method, and it's not guaranteed + /// that this method will provide all extensions. Returns + /// StatusCode::UNIMPLEMENTED if it's not implemented. + /// This field should be a fully-qualified type name. The format is + /// . + package var allExtensionNumbersOfType: String { + get { + if case .allExtensionNumbersOfType(let v)? = messageRequest {return v} + return String() + } + set {messageRequest = .allExtensionNumbersOfType(newValue)} + } + + /// List the full names of registered services. The content will not be + /// checked. + package var listServices: String { + get { + if case .listServices(let v)? = messageRequest {return v} + return String() + } + set {messageRequest = .listServices(newValue)} + } + + package var unknownFields = SwiftProtobuf.UnknownStorage() + + /// To use reflection service, the client should set one of the following + /// fields in message_request. The server distinguishes requests by their + /// defined field and then handles them using corresponding methods. + package enum OneOf_MessageRequest: Equatable, Sendable { + /// Find a proto file by the file name. + case fileByFilename(String) + /// Find the proto file that declares the given fully-qualified symbol name. + /// This field should be a fully-qualified symbol name + /// (e.g. .[.] or .). + case fileContainingSymbol(String) + /// Find the proto file which defines an extension extending the given + /// message type with the given field number. + case fileContainingExtension(Grpc_Reflection_V1_ExtensionRequest) + /// Finds the tag numbers used by all known extensions of the given message + /// type, and appends them to ExtensionNumberResponse in an undefined order. + /// Its corresponding method is best-effort: it's not guaranteed that the + /// reflection service will implement this method, and it's not guaranteed + /// that this method will provide all extensions. Returns + /// StatusCode::UNIMPLEMENTED if it's not implemented. + /// This field should be a fully-qualified type name. The format is + /// . + case allExtensionNumbersOfType(String) + /// List the full names of registered services. The content will not be + /// checked. + case listServices(String) + + } + + package init() {} +} + +/// The type name and extension number sent by the client when requesting +/// file_containing_extension. +package struct Grpc_Reflection_V1_ExtensionRequest: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Fully-qualified type name. The format should be . + package var containingType: String = String() + + package var extensionNumber: Int32 = 0 + + package var unknownFields = SwiftProtobuf.UnknownStorage() + + package init() {} +} + +/// The message sent by the server to answer ServerReflectionInfo method. +package struct Grpc_Reflection_V1_ServerReflectionResponse: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + package var validHost: String = String() + + package var originalRequest: Grpc_Reflection_V1_ServerReflectionRequest { + get {return _originalRequest ?? Grpc_Reflection_V1_ServerReflectionRequest()} + set {_originalRequest = newValue} + } + /// Returns true if `originalRequest` has been explicitly set. + package var hasOriginalRequest: Bool {return self._originalRequest != nil} + /// Clears the value of `originalRequest`. Subsequent reads from it will return its default value. + package mutating func clearOriginalRequest() {self._originalRequest = nil} + + /// The server sets one of the following fields according to the message_request + /// in the request. + package var messageResponse: Grpc_Reflection_V1_ServerReflectionResponse.OneOf_MessageResponse? = nil + + /// This message is used to answer file_by_filename, file_containing_symbol, + /// file_containing_extension requests with transitive dependencies. + /// As the repeated label is not allowed in oneof fields, we use a + /// FileDescriptorResponse message to encapsulate the repeated fields. + /// The reflection service is allowed to avoid sending FileDescriptorProtos + /// that were previously sent in response to earlier requests in the stream. + package var fileDescriptorResponse: Grpc_Reflection_V1_FileDescriptorResponse { + get { + if case .fileDescriptorResponse(let v)? = messageResponse {return v} + return Grpc_Reflection_V1_FileDescriptorResponse() + } + set {messageResponse = .fileDescriptorResponse(newValue)} + } + + /// This message is used to answer all_extension_numbers_of_type requests. + package var allExtensionNumbersResponse: Grpc_Reflection_V1_ExtensionNumberResponse { + get { + if case .allExtensionNumbersResponse(let v)? = messageResponse {return v} + return Grpc_Reflection_V1_ExtensionNumberResponse() + } + set {messageResponse = .allExtensionNumbersResponse(newValue)} + } + + /// This message is used to answer list_services requests. + package var listServicesResponse: Grpc_Reflection_V1_ListServiceResponse { + get { + if case .listServicesResponse(let v)? = messageResponse {return v} + return Grpc_Reflection_V1_ListServiceResponse() + } + set {messageResponse = .listServicesResponse(newValue)} + } + + /// This message is used when an error occurs. + package var errorResponse: Grpc_Reflection_V1_ErrorResponse { + get { + if case .errorResponse(let v)? = messageResponse {return v} + return Grpc_Reflection_V1_ErrorResponse() + } + set {messageResponse = .errorResponse(newValue)} + } + + package var unknownFields = SwiftProtobuf.UnknownStorage() + + /// The server sets one of the following fields according to the message_request + /// in the request. + package enum OneOf_MessageResponse: Equatable, Sendable { + /// This message is used to answer file_by_filename, file_containing_symbol, + /// file_containing_extension requests with transitive dependencies. + /// As the repeated label is not allowed in oneof fields, we use a + /// FileDescriptorResponse message to encapsulate the repeated fields. + /// The reflection service is allowed to avoid sending FileDescriptorProtos + /// that were previously sent in response to earlier requests in the stream. + case fileDescriptorResponse(Grpc_Reflection_V1_FileDescriptorResponse) + /// This message is used to answer all_extension_numbers_of_type requests. + case allExtensionNumbersResponse(Grpc_Reflection_V1_ExtensionNumberResponse) + /// This message is used to answer list_services requests. + case listServicesResponse(Grpc_Reflection_V1_ListServiceResponse) + /// This message is used when an error occurs. + case errorResponse(Grpc_Reflection_V1_ErrorResponse) + + } + + package init() {} + + fileprivate var _originalRequest: Grpc_Reflection_V1_ServerReflectionRequest? = nil +} + +/// Serialized FileDescriptorProto messages sent by the server answering +/// a file_by_filename, file_containing_symbol, or file_containing_extension +/// request. +package struct Grpc_Reflection_V1_FileDescriptorResponse: @unchecked Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Serialized FileDescriptorProto messages. We avoid taking a dependency on + /// descriptor.proto, which uses proto2 only features, by making them opaque + /// bytes instead. + package var fileDescriptorProto: [Data] = [] + + package var unknownFields = SwiftProtobuf.UnknownStorage() + + package init() {} +} + +/// A list of extension numbers sent by the server answering +/// all_extension_numbers_of_type request. +package struct Grpc_Reflection_V1_ExtensionNumberResponse: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Full name of the base type, including the package name. The format + /// is . + package var baseTypeName: String = String() + + package var extensionNumber: [Int32] = [] + + package var unknownFields = SwiftProtobuf.UnknownStorage() + + package init() {} +} + +/// A list of ServiceResponse sent by the server answering list_services request. +package struct Grpc_Reflection_V1_ListServiceResponse: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The information of each service may be expanded in the future, so we use + /// ServiceResponse message to encapsulate it. + package var service: [Grpc_Reflection_V1_ServiceResponse] = [] + + package var unknownFields = SwiftProtobuf.UnknownStorage() + + package init() {} +} + +/// The information of a single service used by ListServiceResponse to answer +/// list_services request. +package struct Grpc_Reflection_V1_ServiceResponse: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Full name of a registered service, including its package name. The format + /// is . + package var name: String = String() + + package var unknownFields = SwiftProtobuf.UnknownStorage() + + package init() {} +} + +/// The error code and error message sent by the server when an error occurs. +package struct Grpc_Reflection_V1_ErrorResponse: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// This field uses the error codes defined in grpc::StatusCode. + package var errorCode: Int32 = 0 + + package var errorMessage: String = String() + + package var unknownFields = SwiftProtobuf.UnknownStorage() + + package init() {} +} + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "grpc.reflection.v1" + +extension Grpc_Reflection_V1_ServerReflectionRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + package static let protoMessageName: String = _protobuf_package + ".ServerReflectionRequest" + package static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "host"), + 3: .standard(proto: "file_by_filename"), + 4: .standard(proto: "file_containing_symbol"), + 5: .standard(proto: "file_containing_extension"), + 6: .standard(proto: "all_extension_numbers_of_type"), + 7: .standard(proto: "list_services"), + ] + + package mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.host) }() + case 3: try { + var v: String? + try decoder.decodeSingularStringField(value: &v) + if let v = v { + if self.messageRequest != nil {try decoder.handleConflictingOneOf()} + self.messageRequest = .fileByFilename(v) + } + }() + case 4: try { + var v: String? + try decoder.decodeSingularStringField(value: &v) + if let v = v { + if self.messageRequest != nil {try decoder.handleConflictingOneOf()} + self.messageRequest = .fileContainingSymbol(v) + } + }() + case 5: try { + var v: Grpc_Reflection_V1_ExtensionRequest? + var hadOneofValue = false + if let current = self.messageRequest { + hadOneofValue = true + if case .fileContainingExtension(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.messageRequest = .fileContainingExtension(v) + } + }() + case 6: try { + var v: String? + try decoder.decodeSingularStringField(value: &v) + if let v = v { + if self.messageRequest != nil {try decoder.handleConflictingOneOf()} + self.messageRequest = .allExtensionNumbersOfType(v) + } + }() + case 7: try { + var v: String? + try decoder.decodeSingularStringField(value: &v) + if let v = v { + if self.messageRequest != nil {try decoder.handleConflictingOneOf()} + self.messageRequest = .listServices(v) + } + }() + default: break + } + } + } + + package func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.host.isEmpty { + try visitor.visitSingularStringField(value: self.host, fieldNumber: 1) + } + switch self.messageRequest { + case .fileByFilename?: try { + guard case .fileByFilename(let v)? = self.messageRequest else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 3) + }() + case .fileContainingSymbol?: try { + guard case .fileContainingSymbol(let v)? = self.messageRequest else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 4) + }() + case .fileContainingExtension?: try { + guard case .fileContainingExtension(let v)? = self.messageRequest else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + }() + case .allExtensionNumbersOfType?: try { + guard case .allExtensionNumbersOfType(let v)? = self.messageRequest else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 6) + }() + case .listServices?: try { + guard case .listServices(let v)? = self.messageRequest else { preconditionFailure() } + try visitor.visitSingularStringField(value: v, fieldNumber: 7) + }() + case nil: break + } + try unknownFields.traverse(visitor: &visitor) + } + + package static func ==(lhs: Grpc_Reflection_V1_ServerReflectionRequest, rhs: Grpc_Reflection_V1_ServerReflectionRequest) -> Bool { + if lhs.host != rhs.host {return false} + if lhs.messageRequest != rhs.messageRequest {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Grpc_Reflection_V1_ExtensionRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + package static let protoMessageName: String = _protobuf_package + ".ExtensionRequest" + package static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "containing_type"), + 2: .standard(proto: "extension_number"), + ] + + package mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.containingType) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self.extensionNumber) }() + default: break + } + } + } + + package func traverse(visitor: inout V) throws { + if !self.containingType.isEmpty { + try visitor.visitSingularStringField(value: self.containingType, fieldNumber: 1) + } + if self.extensionNumber != 0 { + try visitor.visitSingularInt32Field(value: self.extensionNumber, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + package static func ==(lhs: Grpc_Reflection_V1_ExtensionRequest, rhs: Grpc_Reflection_V1_ExtensionRequest) -> Bool { + if lhs.containingType != rhs.containingType {return false} + if lhs.extensionNumber != rhs.extensionNumber {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Grpc_Reflection_V1_ServerReflectionResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + package static let protoMessageName: String = _protobuf_package + ".ServerReflectionResponse" + package static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "valid_host"), + 2: .standard(proto: "original_request"), + 4: .standard(proto: "file_descriptor_response"), + 5: .standard(proto: "all_extension_numbers_response"), + 6: .standard(proto: "list_services_response"), + 7: .standard(proto: "error_response"), + ] + + package mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.validHost) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._originalRequest) }() + case 4: try { + var v: Grpc_Reflection_V1_FileDescriptorResponse? + var hadOneofValue = false + if let current = self.messageResponse { + hadOneofValue = true + if case .fileDescriptorResponse(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.messageResponse = .fileDescriptorResponse(v) + } + }() + case 5: try { + var v: Grpc_Reflection_V1_ExtensionNumberResponse? + var hadOneofValue = false + if let current = self.messageResponse { + hadOneofValue = true + if case .allExtensionNumbersResponse(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.messageResponse = .allExtensionNumbersResponse(v) + } + }() + case 6: try { + var v: Grpc_Reflection_V1_ListServiceResponse? + var hadOneofValue = false + if let current = self.messageResponse { + hadOneofValue = true + if case .listServicesResponse(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.messageResponse = .listServicesResponse(v) + } + }() + case 7: try { + var v: Grpc_Reflection_V1_ErrorResponse? + var hadOneofValue = false + if let current = self.messageResponse { + hadOneofValue = true + if case .errorResponse(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.messageResponse = .errorResponse(v) + } + }() + default: break + } + } + } + + package func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.validHost.isEmpty { + try visitor.visitSingularStringField(value: self.validHost, fieldNumber: 1) + } + try { if let v = self._originalRequest { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + switch self.messageResponse { + case .fileDescriptorResponse?: try { + guard case .fileDescriptorResponse(let v)? = self.messageResponse else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + }() + case .allExtensionNumbersResponse?: try { + guard case .allExtensionNumbersResponse(let v)? = self.messageResponse else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + }() + case .listServicesResponse?: try { + guard case .listServicesResponse(let v)? = self.messageResponse else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + }() + case .errorResponse?: try { + guard case .errorResponse(let v)? = self.messageResponse else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + }() + case nil: break + } + try unknownFields.traverse(visitor: &visitor) + } + + package static func ==(lhs: Grpc_Reflection_V1_ServerReflectionResponse, rhs: Grpc_Reflection_V1_ServerReflectionResponse) -> Bool { + if lhs.validHost != rhs.validHost {return false} + if lhs._originalRequest != rhs._originalRequest {return false} + if lhs.messageResponse != rhs.messageResponse {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Grpc_Reflection_V1_FileDescriptorResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + package static let protoMessageName: String = _protobuf_package + ".FileDescriptorResponse" + package static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "file_descriptor_proto"), + ] + + package mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedBytesField(value: &self.fileDescriptorProto) }() + default: break + } + } + } + + package func traverse(visitor: inout V) throws { + if !self.fileDescriptorProto.isEmpty { + try visitor.visitRepeatedBytesField(value: self.fileDescriptorProto, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + package static func ==(lhs: Grpc_Reflection_V1_FileDescriptorResponse, rhs: Grpc_Reflection_V1_FileDescriptorResponse) -> Bool { + if lhs.fileDescriptorProto != rhs.fileDescriptorProto {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Grpc_Reflection_V1_ExtensionNumberResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + package static let protoMessageName: String = _protobuf_package + ".ExtensionNumberResponse" + package static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "base_type_name"), + 2: .standard(proto: "extension_number"), + ] + + package mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.baseTypeName) }() + case 2: try { try decoder.decodeRepeatedInt32Field(value: &self.extensionNumber) }() + default: break + } + } + } + + package func traverse(visitor: inout V) throws { + if !self.baseTypeName.isEmpty { + try visitor.visitSingularStringField(value: self.baseTypeName, fieldNumber: 1) + } + if !self.extensionNumber.isEmpty { + try visitor.visitPackedInt32Field(value: self.extensionNumber, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + package static func ==(lhs: Grpc_Reflection_V1_ExtensionNumberResponse, rhs: Grpc_Reflection_V1_ExtensionNumberResponse) -> Bool { + if lhs.baseTypeName != rhs.baseTypeName {return false} + if lhs.extensionNumber != rhs.extensionNumber {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Grpc_Reflection_V1_ListServiceResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + package static let protoMessageName: String = _protobuf_package + ".ListServiceResponse" + package static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "service"), + ] + + package mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.service) }() + default: break + } + } + } + + package func traverse(visitor: inout V) throws { + if !self.service.isEmpty { + try visitor.visitRepeatedMessageField(value: self.service, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + package static func ==(lhs: Grpc_Reflection_V1_ListServiceResponse, rhs: Grpc_Reflection_V1_ListServiceResponse) -> Bool { + if lhs.service != rhs.service {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Grpc_Reflection_V1_ServiceResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + package static let protoMessageName: String = _protobuf_package + ".ServiceResponse" + package static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + ] + + package mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.name) }() + default: break + } + } + } + + package func traverse(visitor: inout V) throws { + if !self.name.isEmpty { + try visitor.visitSingularStringField(value: self.name, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + package static func ==(lhs: Grpc_Reflection_V1_ServiceResponse, rhs: Grpc_Reflection_V1_ServiceResponse) -> Bool { + if lhs.name != rhs.name {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Grpc_Reflection_V1_ErrorResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + package static let protoMessageName: String = _protobuf_package + ".ErrorResponse" + package static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "error_code"), + 2: .standard(proto: "error_message"), + ] + + package mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self.errorCode) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.errorMessage) }() + default: break + } + } + } + + package func traverse(visitor: inout V) throws { + if self.errorCode != 0 { + try visitor.visitSingularInt32Field(value: self.errorCode, fieldNumber: 1) + } + if !self.errorMessage.isEmpty { + try visitor.visitSingularStringField(value: self.errorMessage, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + package static func ==(lhs: Grpc_Reflection_V1_ErrorResponse, rhs: Grpc_Reflection_V1_ErrorResponse) -> Bool { + if lhs.errorCode != rhs.errorCode {return false} + if lhs.errorMessage != rhs.errorMessage {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/base_message.pb b/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/base_message.pb new file mode 100644 index 0000000..ecde622 Binary files /dev/null and b/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/base_message.pb differ diff --git a/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/health.pb b/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/health.pb new file mode 100644 index 0000000..ff3b6a7 Binary files /dev/null and b/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/health.pb differ diff --git a/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/message_with_dependency.pb b/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/message_with_dependency.pb new file mode 100644 index 0000000..39d348a Binary files /dev/null and b/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/message_with_dependency.pb differ diff --git a/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/reflection.pb b/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/reflection.pb new file mode 100644 index 0000000..91acee6 Binary files /dev/null and b/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/reflection.pb differ diff --git a/dev/protos/fetch.sh b/dev/protos/fetch.sh index 52d3a7f..ee57c33 100755 --- a/dev/protos/fetch.sh +++ b/dev/protos/fetch.sh @@ -30,6 +30,8 @@ rm -rf "$upstream" # Create new directories to poulate. These are based on proto package name # rather than source repository name. mkdir -p "$upstream/grpc/health/v1" +mkdir -p "$upstream/grpc/reflection/v1" # Copy over the grpc-proto protos. cp -rp "$checkouts/grpc-proto/grpc/health/v1/health.proto" "$upstream/grpc/health/v1/health.proto" +cp -rp "$checkouts/grpc-proto/grpc/reflection/v1/reflection.proto" "$upstream/grpc/reflection/v1/reflection.proto" diff --git a/dev/protos/generate.sh b/dev/protos/generate.sh index 143c40a..5cdfe38 100755 --- a/dev/protos/generate.sh +++ b/dev/protos/generate.sh @@ -94,10 +94,63 @@ function generate_health_service { generate_grpc "$proto" "$(dirname "$proto")" "$output" "Visibility=Package" "Client=true" "Server=true" "UseAccessLevelOnImports=true" } +function generate_reflection_service { + local proto="$here/upstream/grpc/reflection/v1/reflection.proto" + local output="$root/Sources/GRPCReflectionService/Generated" + + generate_message "$proto" "$(dirname "$proto")" "$output" "Visibility=Package" "UseAccessLevelOnImports=true" + generate_grpc "$proto" "$(dirname "$proto")" "$output" "Visibility=Package" "UseAccessLevelOnImports=true" +} + +#- TEST DATA ------------------------------------------------------------------ + +function generate_reflection_service_descriptor_set { + local proto="$here/upstream/grpc/reflection/v1/reflection.proto" + local proto_path="$here/upstream" + local output="$root/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/reflection.pb" + + invoke_protoc --descriptor_set_out="$output" "$proto" -I "$proto_path" \ + --include_source_info \ + --include_imports +} + +function generate_health_service_descriptor_set { + local proto="$here/upstream/grpc/health/v1/health.proto" + local proto_path="$here/upstream" + local output="$root/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/health.pb" + + invoke_protoc --descriptor_set_out="$output" "$proto" -I "$proto_path" \ + --include_source_info \ + --include_imports +} + +function generate_base_message_descriptor_set { + local proto="$here/tests/reflection/base_message.proto" + local proto_path="$here/tests/reflection" + local output="$root/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/base_message.pb" + + invoke_protoc --descriptor_set_out="$output" "$proto" -I "$proto_path" \ + --include_source_info \ + --include_imports +} + +function generate_message_with_dependency_descriptor_set { + local proto="$here/tests/reflection/message_with_dependency.proto" + local proto_path="$here/tests/reflection" + local output="$root/Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/message_with_dependency.pb" + + invoke_protoc --descriptor_set_out="$output" "$proto" -I "$proto_path" \ + --include_source_info \ + --include_imports +} + #------------------------------------------------------------------------------ -# Interoperability tests generate_interop_test_service - -# Health service generate_health_service +generate_reflection_service + +generate_reflection_service_descriptor_set +generate_health_service_descriptor_set +generate_base_message_descriptor_set +generate_message_with_dependency_descriptor_set diff --git a/dev/protos/tests/reflection/base_message.proto b/dev/protos/tests/reflection/base_message.proto new file mode 100644 index 0000000..532e3e0 --- /dev/null +++ b/dev/protos/tests/reflection/base_message.proto @@ -0,0 +1,11 @@ +syntax = "proto2"; + +message BaseMessage { + required string id = 1; + + extensions 100 to 101; +} + +extend BaseMessage { + optional int32 extended_field = 100; +} diff --git a/dev/protos/tests/reflection/message_with_dependency.proto b/dev/protos/tests/reflection/message_with_dependency.proto new file mode 100644 index 0000000..384661a --- /dev/null +++ b/dev/protos/tests/reflection/message_with_dependency.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +import "google/protobuf/empty.proto"; + +message MessageWithDependency { + google.protobuf.Empty empty = 1; +} diff --git a/dev/protos/upstream/grpc/reflection/v1/reflection.proto b/dev/protos/upstream/grpc/reflection/v1/reflection.proto new file mode 100644 index 0000000..1a2ceed --- /dev/null +++ b/dev/protos/upstream/grpc/reflection/v1/reflection.proto @@ -0,0 +1,147 @@ +// Copyright 2016 The gRPC Authors +// +// 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. + +// Service exported by server reflection. A more complete description of how +// server reflection works can be found at +// https://github.com/grpc/grpc/blob/master/doc/server-reflection.md +// +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto + +syntax = "proto3"; + +package grpc.reflection.v1; + +option go_package = "google.golang.org/grpc/reflection/grpc_reflection_v1"; +option java_multiple_files = true; +option java_package = "io.grpc.reflection.v1"; +option java_outer_classname = "ServerReflectionProto"; + +service ServerReflection { + // The reflection service is structured as a bidirectional stream, ensuring + // all related requests go to a single server. + rpc ServerReflectionInfo(stream ServerReflectionRequest) + returns (stream ServerReflectionResponse); +} + +// The message sent by the client when calling ServerReflectionInfo method. +message ServerReflectionRequest { + string host = 1; + // To use reflection service, the client should set one of the following + // fields in message_request. The server distinguishes requests by their + // defined field and then handles them using corresponding methods. + oneof message_request { + // Find a proto file by the file name. + string file_by_filename = 3; + + // Find the proto file that declares the given fully-qualified symbol name. + // This field should be a fully-qualified symbol name + // (e.g. .[.] or .). + string file_containing_symbol = 4; + + // Find the proto file which defines an extension extending the given + // message type with the given field number. + ExtensionRequest file_containing_extension = 5; + + // Finds the tag numbers used by all known extensions of the given message + // type, and appends them to ExtensionNumberResponse in an undefined order. + // Its corresponding method is best-effort: it's not guaranteed that the + // reflection service will implement this method, and it's not guaranteed + // that this method will provide all extensions. Returns + // StatusCode::UNIMPLEMENTED if it's not implemented. + // This field should be a fully-qualified type name. The format is + // . + string all_extension_numbers_of_type = 6; + + // List the full names of registered services. The content will not be + // checked. + string list_services = 7; + } +} + +// The type name and extension number sent by the client when requesting +// file_containing_extension. +message ExtensionRequest { + // Fully-qualified type name. The format should be . + string containing_type = 1; + int32 extension_number = 2; +} + +// The message sent by the server to answer ServerReflectionInfo method. +message ServerReflectionResponse { + string valid_host = 1; + ServerReflectionRequest original_request = 2; + // The server sets one of the following fields according to the message_request + // in the request. + oneof message_response { + // This message is used to answer file_by_filename, file_containing_symbol, + // file_containing_extension requests with transitive dependencies. + // As the repeated label is not allowed in oneof fields, we use a + // FileDescriptorResponse message to encapsulate the repeated fields. + // The reflection service is allowed to avoid sending FileDescriptorProtos + // that were previously sent in response to earlier requests in the stream. + FileDescriptorResponse file_descriptor_response = 4; + + // This message is used to answer all_extension_numbers_of_type requests. + ExtensionNumberResponse all_extension_numbers_response = 5; + + // This message is used to answer list_services requests. + ListServiceResponse list_services_response = 6; + + // This message is used when an error occurs. + ErrorResponse error_response = 7; + } +} + +// Serialized FileDescriptorProto messages sent by the server answering +// a file_by_filename, file_containing_symbol, or file_containing_extension +// request. +message FileDescriptorResponse { + // Serialized FileDescriptorProto messages. We avoid taking a dependency on + // descriptor.proto, which uses proto2 only features, by making them opaque + // bytes instead. + repeated bytes file_descriptor_proto = 1; +} + +// A list of extension numbers sent by the server answering +// all_extension_numbers_of_type request. +message ExtensionNumberResponse { + // Full name of the base type, including the package name. The format + // is . + string base_type_name = 1; + repeated int32 extension_number = 2; +} + +// A list of ServiceResponse sent by the server answering list_services request. +message ListServiceResponse { + // The information of each service may be expanded in the future, so we use + // ServiceResponse message to encapsulate it. + repeated ServiceResponse service = 1; +} + +// The information of a single service used by ListServiceResponse to answer +// list_services request. +message ServiceResponse { + // Full name of a registered service, including its package name. The format + // is . + string name = 1; +} + +// The error code and error message sent by the server when an error occurs. +message ErrorResponse { + // This field uses the error codes defined in grpc::StatusCode. + int32 error_code = 1; + string error_message = 2; +} +