2
0

ReflectionServiceV1.swift 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * Copyright 2023, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import Foundation
  17. import GRPC
  18. import SwiftProtobuf
  19. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  20. internal final class ReflectionServiceProviderV1: Grpc_Reflection_V1_ServerReflectionAsyncProvider {
  21. private let protoRegistry: ReflectionServiceData
  22. internal init(fileDescriptorProtos: [Google_Protobuf_FileDescriptorProto]) throws {
  23. self.protoRegistry = try ReflectionServiceData(
  24. fileDescriptors: fileDescriptorProtos
  25. )
  26. }
  27. internal func _findFileByFileName(
  28. _ fileName: String
  29. ) -> Result<Grpc_Reflection_V1_ServerReflectionResponse.OneOf_MessageResponse, GRPCStatus> {
  30. return self.protoRegistry
  31. .serialisedFileDescriptorProtosForDependenciesOfFile(named: fileName)
  32. .map { fileDescriptorProtos in
  33. Grpc_Reflection_V1_ServerReflectionResponse.OneOf_MessageResponse.fileDescriptorResponse(
  34. .with {
  35. $0.fileDescriptorProto = fileDescriptorProtos
  36. }
  37. )
  38. }
  39. }
  40. internal func findFileByFileName(
  41. _ fileName: String,
  42. request: Grpc_Reflection_V1_ServerReflectionRequest
  43. ) -> Grpc_Reflection_V1_ServerReflectionResponse {
  44. let result = self._findFileByFileName(fileName)
  45. return result.makeResponse(request: request)
  46. }
  47. internal func getServicesNames(
  48. request: Grpc_Reflection_V1_ServerReflectionRequest
  49. ) throws -> Grpc_Reflection_V1_ServerReflectionResponse {
  50. var listServicesResponse = Grpc_Reflection_V1_ListServiceResponse()
  51. listServicesResponse.service = self.protoRegistry.serviceNames.map { serviceName in
  52. Grpc_Reflection_V1_ServiceResponse.with {
  53. $0.name = serviceName
  54. }
  55. }
  56. return Grpc_Reflection_V1_ServerReflectionResponse(
  57. request: request,
  58. messageResponse: .listServicesResponse(listServicesResponse)
  59. )
  60. }
  61. internal func findFileBySymbol(
  62. _ symbolName: String,
  63. request: Grpc_Reflection_V1_ServerReflectionRequest
  64. ) -> Grpc_Reflection_V1_ServerReflectionResponse {
  65. let result = self.protoRegistry.nameOfFileContainingSymbol(
  66. named: symbolName
  67. ).flatMap {
  68. self._findFileByFileName($0)
  69. }
  70. return result.makeResponse(request: request)
  71. }
  72. internal func findFileByExtension(
  73. extensionRequest: Grpc_Reflection_V1_ExtensionRequest,
  74. request: Grpc_Reflection_V1_ServerReflectionRequest
  75. ) -> Grpc_Reflection_V1_ServerReflectionResponse {
  76. let result = self.protoRegistry.nameOfFileContainingExtension(
  77. extendeeName: extensionRequest.containingType,
  78. fieldNumber: extensionRequest.extensionNumber
  79. ).flatMap {
  80. self._findFileByFileName($0)
  81. }
  82. return result.makeResponse(request: request)
  83. }
  84. internal func findExtensionsFieldNumbersOfType(
  85. named typeName: String,
  86. request: Grpc_Reflection_V1_ServerReflectionRequest
  87. ) -> Grpc_Reflection_V1_ServerReflectionResponse {
  88. let result = self.protoRegistry.extensionsFieldNumbersOfType(
  89. named: typeName
  90. ).map { fieldNumbers in
  91. Grpc_Reflection_V1_ServerReflectionResponse.OneOf_MessageResponse.allExtensionNumbersResponse(
  92. Grpc_Reflection_V1_ExtensionNumberResponse.with {
  93. $0.baseTypeName = typeName
  94. $0.extensionNumber = fieldNumbers
  95. }
  96. )
  97. }
  98. return result.makeResponse(request: request)
  99. }
  100. internal func serverReflectionInfo(
  101. requestStream: GRPCAsyncRequestStream<Grpc_Reflection_V1_ServerReflectionRequest>,
  102. responseStream: GRPCAsyncResponseStreamWriter<Grpc_Reflection_V1_ServerReflectionResponse>,
  103. context: GRPCAsyncServerCallContext
  104. ) async throws {
  105. for try await request in requestStream {
  106. switch request.messageRequest {
  107. case let .fileByFilename(fileName):
  108. let response = self.findFileByFileName(
  109. fileName,
  110. request: request
  111. )
  112. try await responseStream.send(response)
  113. case .listServices:
  114. let response = try self.getServicesNames(request: request)
  115. try await responseStream.send(response)
  116. case let .fileContainingSymbol(symbolName):
  117. let response = self.findFileBySymbol(
  118. symbolName,
  119. request: request
  120. )
  121. try await responseStream.send(response)
  122. case let .fileContainingExtension(extensionRequest):
  123. let response = self.findFileByExtension(
  124. extensionRequest: extensionRequest,
  125. request: request
  126. )
  127. try await responseStream.send(response)
  128. case let .allExtensionNumbersOfType(typeName):
  129. let response = self.findExtensionsFieldNumbersOfType(
  130. named: typeName,
  131. request: request
  132. )
  133. try await responseStream.send(response)
  134. default:
  135. let response = Grpc_Reflection_V1_ServerReflectionResponse(
  136. request: request,
  137. messageResponse: .errorResponse(
  138. Grpc_Reflection_V1_ErrorResponse.with {
  139. $0.errorCode = Int32(GRPCStatus.Code.unimplemented.rawValue)
  140. $0.errorMessage = "The request is not implemented."
  141. }
  142. )
  143. )
  144. try await responseStream.send(response)
  145. }
  146. }
  147. }
  148. }
  149. extension Grpc_Reflection_V1_ServerReflectionResponse {
  150. init(
  151. request: Grpc_Reflection_V1_ServerReflectionRequest,
  152. messageResponse: Grpc_Reflection_V1_ServerReflectionResponse.OneOf_MessageResponse
  153. ) {
  154. self = .with {
  155. $0.validHost = request.host
  156. $0.originalRequest = request
  157. $0.messageResponse = messageResponse
  158. }
  159. }
  160. }
  161. extension Result<Grpc_Reflection_V1_ServerReflectionResponse.OneOf_MessageResponse, GRPCStatus> {
  162. func recover() -> Result<Grpc_Reflection_V1_ServerReflectionResponse.OneOf_MessageResponse, Never>
  163. {
  164. self.flatMapError { status in
  165. let error = Grpc_Reflection_V1_ErrorResponse.with {
  166. $0.errorCode = Int32(status.code.rawValue)
  167. $0.errorMessage = status.message ?? ""
  168. }
  169. return .success(.errorResponse(error))
  170. }
  171. }
  172. func makeResponse(
  173. request: Grpc_Reflection_V1_ServerReflectionRequest
  174. ) -> Grpc_Reflection_V1_ServerReflectionResponse {
  175. let result = self.recover().attachRequest(request)
  176. return result.get()
  177. }
  178. }
  179. extension Result
  180. where Success == Grpc_Reflection_V1_ServerReflectionResponse.OneOf_MessageResponse {
  181. func attachRequest(
  182. _ request: Grpc_Reflection_V1_ServerReflectionRequest
  183. ) -> Result<Grpc_Reflection_V1_ServerReflectionResponse, Failure> {
  184. self.map { message in
  185. Grpc_Reflection_V1_ServerReflectionResponse(request: request, messageResponse: message)
  186. }
  187. }
  188. }