StructuredSwift+ServiceMetadata.swift 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * Copyright 2024, 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. extension TypealiasDescription {
  17. /// `typealias Input = <name>`
  18. package static func methodInput(
  19. accessModifier: AccessModifier? = nil,
  20. name: String
  21. ) -> Self {
  22. return TypealiasDescription(
  23. accessModifier: accessModifier,
  24. name: "Input",
  25. existingType: .member(name)
  26. )
  27. }
  28. /// `typealias Output = <name>`
  29. package static func methodOutput(
  30. accessModifier: AccessModifier? = nil,
  31. name: String
  32. ) -> Self {
  33. return TypealiasDescription(
  34. accessModifier: accessModifier,
  35. name: "Output",
  36. existingType: .member(name)
  37. )
  38. }
  39. }
  40. extension VariableDescription {
  41. /// ```
  42. /// static let descriptor = GRPCCore.MethodDescriptor(
  43. /// service: <serviceNamespace>.descriptor.fullyQualifiedService,
  44. /// method: "<literalMethodName>"
  45. /// ```
  46. package static func methodDescriptor(
  47. accessModifier: AccessModifier? = nil,
  48. serviceNamespace: String,
  49. literalMethodName: String
  50. ) -> Self {
  51. return VariableDescription(
  52. accessModifier: accessModifier,
  53. isStatic: true,
  54. kind: .let,
  55. left: .identifier(.pattern("descriptor")),
  56. right: .functionCall(
  57. FunctionCallDescription(
  58. calledExpression: .identifierType(.methodDescriptor),
  59. arguments: [
  60. FunctionArgumentDescription(
  61. label: "service",
  62. expression: .identifierType(
  63. .member([serviceNamespace, "descriptor"])
  64. ).dot("fullyQualifiedService")
  65. ),
  66. FunctionArgumentDescription(
  67. label: "method",
  68. expression: .literal(literalMethodName)
  69. ),
  70. ]
  71. )
  72. )
  73. )
  74. }
  75. /// ```
  76. /// static let descriptor = GRPCCore.ServiceDescriptor.<namespacedProperty>
  77. /// ```
  78. package static func serviceDescriptor(
  79. accessModifier: AccessModifier? = nil,
  80. namespacedProperty: String
  81. ) -> Self {
  82. return VariableDescription(
  83. accessModifier: accessModifier,
  84. isStatic: true,
  85. kind: .let,
  86. left: .identifierPattern("descriptor"),
  87. right: .identifier(.type(.serviceDescriptor)).dot(namespacedProperty)
  88. )
  89. }
  90. }
  91. extension ExtensionDescription {
  92. /// ```
  93. /// extension GRPCCore.ServiceDescriptor {
  94. /// static let <PropertyName> = Self(
  95. /// package: "<LiteralNamespaceName>",
  96. /// service: "<LiteralServiceName>"
  97. /// )
  98. /// }
  99. /// ```
  100. package static func serviceDescriptor(
  101. accessModifier: AccessModifier? = nil,
  102. propertyName: String,
  103. literalNamespace: String,
  104. literalService: String
  105. ) -> ExtensionDescription {
  106. return ExtensionDescription(
  107. onType: "GRPCCore.ServiceDescriptor",
  108. declarations: [
  109. .variable(
  110. accessModifier: accessModifier,
  111. isStatic: true,
  112. kind: .let,
  113. left: .identifier(.pattern(propertyName)),
  114. right: .functionCall(
  115. calledExpression: .identifierType(.member("Self")),
  116. arguments: [
  117. FunctionArgumentDescription(
  118. label: "package",
  119. expression: .literal(literalNamespace)
  120. ),
  121. FunctionArgumentDescription(
  122. label: "service",
  123. expression: .literal(literalService)
  124. ),
  125. ]
  126. )
  127. )
  128. ]
  129. )
  130. }
  131. }
  132. extension VariableDescription {
  133. /// ```
  134. /// static let descriptors: [GRPCCore.MethodDescriptor] = [<Name1>.descriptor, ...]
  135. /// ```
  136. package static func methodDescriptorsArray(
  137. accessModifier: AccessModifier? = nil,
  138. methodNamespaceNames names: [String]
  139. ) -> Self {
  140. return VariableDescription(
  141. accessModifier: accessModifier,
  142. isStatic: true,
  143. kind: .let,
  144. left: .identifier(.pattern("descriptors")),
  145. type: .array(.methodDescriptor),
  146. right: .literal(.array(names.map { name in .identifierPattern(name).dot("descriptor") }))
  147. )
  148. }
  149. }
  150. extension EnumDescription {
  151. /// ```
  152. /// enum <Method> {
  153. /// typealias Input = <InputType>
  154. /// typealias Output = <OutputType>
  155. /// static let descriptor = GRPCCore.MethodDescriptor(
  156. /// service: <ServiceNamespace>.descriptor.fullyQualifiedService,
  157. /// method: "<LiteralMethod>"
  158. /// )
  159. /// }
  160. /// ```
  161. package static func methodNamespace(
  162. accessModifier: AccessModifier? = nil,
  163. name: String,
  164. literalMethod: String,
  165. serviceNamespace: String,
  166. inputType: String,
  167. outputType: String
  168. ) -> Self {
  169. return EnumDescription(
  170. accessModifier: accessModifier,
  171. name: name,
  172. members: [
  173. .typealias(.methodInput(accessModifier: accessModifier, name: inputType)),
  174. .typealias(.methodOutput(accessModifier: accessModifier, name: outputType)),
  175. .variable(
  176. .methodDescriptor(
  177. accessModifier: accessModifier,
  178. serviceNamespace: serviceNamespace,
  179. literalMethodName: literalMethod
  180. )
  181. ),
  182. ]
  183. )
  184. }
  185. /// ```
  186. /// enum Method {
  187. /// enum <Method> {
  188. /// typealias Input = <MethodInput>
  189. /// typealias Output = <MethodOutput>
  190. /// static let descriptor = GRPCCore.MethodDescriptor(
  191. /// service: <serviceNamespaceName>.descriptor.fullyQualifiedService,
  192. /// method: "<Method>"
  193. /// )
  194. /// }
  195. /// ...
  196. /// static let descriptors: [GRPCCore.MethodDescriptor] = [
  197. /// <Method>.descriptor,
  198. /// ...
  199. /// ]
  200. /// }
  201. /// ```
  202. package static func methodsNamespace(
  203. accessModifier: AccessModifier? = nil,
  204. serviceNamespace: String,
  205. methods: [MethodDescriptor]
  206. ) -> EnumDescription {
  207. var description = EnumDescription(accessModifier: accessModifier, name: "Method")
  208. // Add a namespace for each method.
  209. let methodNamespaces: [Declaration] = methods.map { method in
  210. return .enum(
  211. .methodNamespace(
  212. accessModifier: accessModifier,
  213. name: method.name.base,
  214. literalMethod: method.name.base,
  215. serviceNamespace: serviceNamespace,
  216. inputType: method.inputType,
  217. outputType: method.outputType
  218. )
  219. )
  220. }
  221. description.members.append(contentsOf: methodNamespaces)
  222. // Add an array of method descriptors
  223. let methodDescriptorsArray: VariableDescription = .methodDescriptorsArray(
  224. accessModifier: accessModifier,
  225. methodNamespaceNames: methods.map { $0.name.base }
  226. )
  227. description.members.append(.variable(methodDescriptorsArray))
  228. return description
  229. }
  230. /// ```
  231. /// enum <Name> {
  232. /// static let descriptor = GRPCCore.ServiceDescriptor.<namespacedServicePropertyName>
  233. /// enum Method {
  234. /// ...
  235. /// }
  236. /// @available(...)
  237. /// typealias StreamingServiceProtocol = ...
  238. /// @available(...)
  239. /// typealias ServiceProtocol = ...
  240. /// ...
  241. /// }
  242. /// ```
  243. package static func serviceNamespace(
  244. accessModifier: AccessModifier? = nil,
  245. name: String,
  246. serviceDescriptorProperty: String,
  247. client: Bool,
  248. server: Bool,
  249. methods: [MethodDescriptor]
  250. ) -> EnumDescription {
  251. var description = EnumDescription(accessModifier: accessModifier, name: name)
  252. // static let descriptor = GRPCCore.ServiceDescriptor.<namespacedServicePropertyName>
  253. let descriptor = VariableDescription.serviceDescriptor(
  254. accessModifier: accessModifier,
  255. namespacedProperty: serviceDescriptorProperty
  256. )
  257. description.members.append(.variable(descriptor))
  258. // enum Method { ... }
  259. let methodsNamespace: EnumDescription = .methodsNamespace(
  260. accessModifier: accessModifier,
  261. serviceNamespace: name,
  262. methods: methods
  263. )
  264. description.members.append(.enum(methodsNamespace))
  265. // Typealiases for the various protocols.
  266. var typealiasNames: [String] = []
  267. if server {
  268. typealiasNames.append("StreamingServiceProtocol")
  269. typealiasNames.append("ServiceProtocol")
  270. }
  271. if client {
  272. typealiasNames.append("ClientProtocol")
  273. typealiasNames.append("Client")
  274. }
  275. let typealiases: [Declaration] = typealiasNames.map { alias in
  276. .guarded(
  277. .grpc,
  278. .typealias(
  279. accessModifier: accessModifier,
  280. name: alias,
  281. existingType: .member(name + "_" + alias)
  282. )
  283. )
  284. }
  285. description.members.append(contentsOf: typealiases)
  286. return description
  287. }
  288. }