Skip to content

Commit 4a6117d

Browse files
authored
Merge branch 'main' into v2/with-client-server
2 parents 706f5b4 + c960d06 commit 4a6117d

File tree

6 files changed

+755
-2
lines changed

6 files changed

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

0 commit comments

Comments
 (0)