From 6bd9fe8197212de05c280d9036fe6e3999212e16 Mon Sep 17 00:00:00 2001 From: George Barnett Date: Fri, 20 Dec 2024 11:04:36 +0000 Subject: [PATCH 1/3] Update fetch and generate scripts for reflection Motivation: To add the reflection service we need to fetch it and generate the appropriate code. Modifications: - Update proto fetching script to get v1 reflection service - Update proto generating script to generate reflection service code and messages - Also add protos used in tests for the reflection service and generate their descriptor sets Result: Generated code is in place --- .../Generated/reflection.grpc.swift | 346 ++++++++ .../Generated/reflection.pb.swift | 775 ++++++++++++++++++ .../Generated/DescriptorSets/base_message.pb | Bin 0 -> 362 bytes .../Generated/DescriptorSets/health.pb | Bin 0 -> 3431 bytes .../DescriptorSets/message_with_dependency.pb | Bin 0 -> 2558 bytes .../Generated/DescriptorSets/reflection.pb | Bin 0 -> 7655 bytes dev/protos/fetch.sh | 2 + dev/protos/generate.sh | 61 +- .../tests/reflection/base_message.proto | 11 + .../reflection/message_with_dependency.proto | 7 + .../grpc/reflection/v1/reflection.proto | 147 ++++ 11 files changed, 1346 insertions(+), 3 deletions(-) create mode 100644 Sources/GRPCReflectionService/Generated/reflection.grpc.swift create mode 100644 Sources/GRPCReflectionService/Generated/reflection.pb.swift create mode 100644 Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/base_message.pb create mode 100644 Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/health.pb create mode 100644 Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/message_with_dependency.pb create mode 100644 Tests/GRPCReflectionServiceTests/Generated/DescriptorSets/reflection.pb create mode 100644 dev/protos/tests/reflection/base_message.proto create mode 100644 dev/protos/tests/reflection/message_with_dependency.proto create mode 100644 dev/protos/upstream/grpc/reflection/v1/reflection.proto 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 0000000000000000000000000000000000000000..ecde6220c8129dbb70776254d46e1f5484875278 GIT binary patch literal 362 zcmYk0u}%Xq5JcB&J7@3RMVBSg9Tia!D56M1M@d0}M3Wzgg6yD3KoFOLKjsgpSz}qE zo41;o9r{M%=iL~$Z*d%VFLC|xc|0ALmsH=&^(h~DN_Yr^THwlWMBNw{y8YcPP2<-o zzK0mL`$K#U+^qklhOkg8yJ?H(Az2=O6iwIwkRnH_VGY1Uga+6kOq6JCK(R)5Ml~4& z2&^@pQ$sd^NkoOLP(3RoG0pQrTBsj#q4+EgxzI|XZToDq>6dN0LMSxv$&;$sxHQuf lR+8{|ovJDjhpW^7G5hX~7mPcMmhP<{{-elXf*K0d8X(<&Sl2oc>S}Qa5k}6WNYjbgdz>u6W z2p||hTpjawa!6GwN#&dza?UTvDL*8y2OpHYyFNt+Y8uni)BXB&_lW=QiaWC;_PTTF z2I;(ewpXk=aT2AGv&oyCe6w@5*Xju8rP1uorT2a$f1gR6I=96YEt50l$=eoL53i0& zvGr$5>|8pa<0#b9>5HaL-89qYz~=s5=ki6JA2`$*^Bv)AYz~eJ1FfO>qXw-Y4?}lf_j`wf@!=CVivy=& zAho6hm7o#?IXNdchAW;sfrEj&q$nYGmPqWS5xcrfR0$_q@*mkX6a~hx5KNZ)+8VhSIt(OuMKfk(NN)1RmH;g&UvA?K& zm7BAm^~L%fXxX;K7g7DohB*TXdvxW7_(U{$k1xAxZ;MTFB^R-M*WOskfadPzR;7;Z z)&+IGsdYh}k!)R1hj`DvQCX`){hqzGl6fE9w_7-ac<$S`TSTYaD55Yp=R#uEnPy1~ ziEaXNRt6d{c;DVx$uM~T<}CxH#j!o8GYo4sgeFT{rG$eIwr`daE`IRYuK1@V>P_I) zMuXe^n?-r!c83jOM}c9qnU&o3~S!%%NAIaHascDIQ-3iM2k6Y)DlP>O)I%!^8Swn1mMQG}()9xsVnEC#1_n-Y1`RH4Zd#_<_|gkFIlxGi zInBcSf^$*^lykUmd{3k&)tQ9tR4pVpo4cr`@qsyF+N$I%7rn6X2t7^tauG){kiK$Lj#Ep(HE|K2i^|ZNhk*)xG;*G7 zIV-XxL2NmQ{4u9QhfoPQTL5uLI-6*wSeTY(T?*y0vdX!V$g?m;3wEL&&8o6WT%0qh z8TTI}?gifF4B#>_+y$YFO!|g*RpL$DCe~G$;8GRi2Tr6Bh9|!@SFcIJOwXfzjMvL! z!c1DI5Fl2S!+=aN+VC1!fO69;%|O36QenC(f)##M#d03;*qKO-K&fd}k3Z=BB}mKn z(T|~d0Y!sP<+Q$3+^2*7H^;9Jzd0P79O6k~(&^=e2OsjvbG1f~!yYisdpM_oA96a2 z<0#?A!lhTJ^F|`m#I$~4vXkRe?S3nAF9v`GM^C}zIud*QQ=Z~MP)wE zz3EnXuq9EPFuD0j6osIp!kdH{9!;lJDe}-es!EYZ-cePG7N*S6qi#`{77Fv|X>Zar IPm-Vi4`LkMCjbBd literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..39d348a80b5fe62111513adcd5328add889b4e97 GIT binary patch literal 2558 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 literal 0 HcmV?d00001 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..9474e0f 100755 --- a/dev/protos/generate.sh +++ b/dev/protos/generate.sh @@ -94,10 +94,65 @@ 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" + + # Messages were accidentally leaked into public API, they shouldn't be but we + # can't undo that change until the next major version. + 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_extended_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_extended_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; +} + From 99f81a8231e961a7212343308ea0676ee909f514 Mon Sep 17 00:00:00 2001 From: George Barnett Date: Fri, 20 Dec 2024 11:13:19 +0000 Subject: [PATCH 2/3] Ignore pb files in license check --- .licenseignore | 1 + 1 file changed, 1 insertion(+) 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 From da069695740db0cb64150641274705402124b447 Mon Sep 17 00:00:00 2001 From: George Barnett Date: Fri, 20 Dec 2024 11:45:54 +0000 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Gus Cairo --- dev/protos/generate.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dev/protos/generate.sh b/dev/protos/generate.sh index 9474e0f..5cdfe38 100755 --- a/dev/protos/generate.sh +++ b/dev/protos/generate.sh @@ -98,8 +98,6 @@ function generate_reflection_service { local proto="$here/upstream/grpc/reflection/v1/reflection.proto" local output="$root/Sources/GRPCReflectionService/Generated" - # Messages were accidentally leaked into public API, they shouldn't be but we - # can't undo that change until the next major version. generate_message "$proto" "$(dirname "$proto")" "$output" "Visibility=Package" "UseAccessLevelOnImports=true" generate_grpc "$proto" "$(dirname "$proto")" "$output" "Visibility=Package" "UseAccessLevelOnImports=true" } @@ -126,7 +124,7 @@ function generate_health_service_descriptor_set { --include_imports } -function generate_extended_message_descriptor_set { +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" @@ -154,5 +152,5 @@ generate_reflection_service generate_reflection_service_descriptor_set generate_health_service_descriptor_set -generate_extended_message_descriptor_set +generate_base_message_descriptor_set generate_message_with_dependency_descriptor_set