Skip to content

Commit 951cbed

Browse files
stefanadrancaglbrntt
authored andcommitted
[CodeGenLib] Translator for enums containing type aliases and static properties (grpc#1733)
Motivation: In the generated code we want to have: - enums for each namespace containing enums for all their services - enums for each service (inside the corresponding namespace enum) containing enums for all their methods, an array of all corresponding MethodDescriptors and type aliases for streaming and non-streaming protocols - enums for each method (inside the corresponding service enum) containing type aliases for the input and output types and a method descriptor (GRPCCore) Modifications: - Created the Translator protocol defining the 'translate()' function. - Implemented the IDLToStructuredSwiftTranslator struct which conforms to the Translator protocol and creates the StructuredSwiftRepresentation for a CodeGenerationRequest calling the Specialized translators' functions. - Created the SpecializedTranslator protocol. - Implemented the TypeAliasTranslator, the first of the 3 SpecializedTranslators that takes in a CodeGenerationRequest object and creates all the enums, type aliases and properties mentioned in the Motivation, in StructuredSwiftRepresentation format. - Created CodeGenError. - Wrote SnippetTests. Result: The generated code will contain useful type aliases for message types and protocol names, organized in namespace, service and method specific enums.
1 parent c07c039 commit 951cbed

File tree

10 files changed

+1070
-6
lines changed

10 files changed

+1070
-6
lines changed

NOTICES.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ This product uses derivations of swift-extras/swift-extras-base64 'Base64.swift'
6262

6363
This product uses derivations of apple/swift-openapi-generator 'StructuredSwiftRepresentation.swift',
6464
'TypeName.swift', 'TypeUsage.swift', 'Builtins.swift', 'RendererProtocol.swift', 'TextBasedProtocol',
65-
and 'Test_TextBasedRenderer'.
65+
'Test_TextBasedRenderer', and 'SnippetBasedReferenceTests.swift'.
6666

6767
* LICENSE (Apache License 2.0):
6868
* https://github.com/apple/swift-openapi-generator/blob/main/LICENSE.txt
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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+
17+
/// A error thrown by the ``SourceGenerator`` to signal errors in the ``CodeGenerationRequest`` object.
18+
public struct CodeGenError: Error, Hashable, Sendable {
19+
/// The code indicating the domain of the error.
20+
public var code: Code
21+
/// A message providing more details about the error which may include details specific to this
22+
/// instance of the error.
23+
public var message: String
24+
25+
/// Creates a new error.
26+
///
27+
/// - Parameters:
28+
/// - code: The error code.
29+
/// - message: A description of the error.
30+
public init(code: Code, message: String) {
31+
self.code = code
32+
self.message = message
33+
}
34+
}
35+
36+
extension CodeGenError {
37+
public struct Code: Hashable, Sendable {
38+
private enum Value {
39+
case nonUniqueServiceName
40+
case nonUniqueMethodName
41+
}
42+
43+
private var value: Value
44+
private init(_ value: Value) {
45+
self.value = value
46+
}
47+
48+
/// The same name is used for two services that are either in the same namespace or don't have a namespace.
49+
public static var nonUniqueServiceName: Self {
50+
Self(.nonUniqueServiceName)
51+
}
52+
53+
/// The same name is used for two methods of the same service.
54+
public static var nonUniqueMethodName: Self {
55+
Self(.nonUniqueMethodName)
56+
}
57+
}
58+
}
59+
60+
extension CodeGenError: CustomStringConvertible {
61+
public var description: String {
62+
return "\(self.code): \"\(self.message)\""
63+
}
64+
}

Sources/GRPCCodeGen/CodeGenerationRequest.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public struct CodeGenerationRequest {
3636
public var services: [ServiceDescriptor]
3737

3838
/// Closure that receives a message type as a `String` and returns a code snippet to
39-
/// initialize a `MessageSerializer` for that type as a `String`.
39+
/// initialise a `MessageSerializer` for that type as a `String`.
4040
///
4141
/// The result is inserted in the generated code, where clients serialize RPC inputs and
4242
/// servers serialize RPC outputs.
@@ -217,22 +217,22 @@ public struct CodeGenerationRequest {
217217
public var inputType: String
218218

219219
/// The generated output type for the described method.
220-
public var ouputType: String
220+
public var outputType: String
221221

222222
public init(
223223
documentation: String,
224224
name: String,
225225
isInputStreaming: Bool,
226226
isOutputStreaming: Bool,
227227
inputType: String,
228-
ouputType: String
228+
outputType: String
229229
) {
230230
self.documentation = documentation
231231
self.name = name
232232
self.isInputStreaming = isInputStreaming
233233
self.isOutputStreaming = isOutputStreaming
234234
self.inputType = inputType
235-
self.ouputType = ouputType
235+
self.outputType = outputType
236236
}
237237
}
238238
}

Sources/GRPCCodeGen/Internal/StructuredSwiftRepresentation.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ struct ImportDescription: Equatable, Codable {
6666
///
6767
/// For example: `public`.
6868
internal enum AccessModifier: String, Sendable, Equatable, Codable {
69-
7069
/// A declaration accessible outside of the module.
7170
case `public`
7271

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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+
17+
struct IDLToStructuredSwiftTranslator: Translator {
18+
private let typealiasTranslator = TypealiasTranslator()
19+
20+
func translate(
21+
codeGenerationRequest: CodeGenerationRequest,
22+
client: Bool,
23+
server: Bool
24+
) throws -> StructuredSwiftRepresentation {
25+
let topComment = Comment.doc(codeGenerationRequest.leadingTrivia)
26+
let imports: [ImportDescription] = [
27+
ImportDescription(moduleName: "GRPCCore")
28+
]
29+
var codeBlocks: [CodeBlock] = []
30+
codeBlocks.append(
31+
contentsOf: try self.typealiasTranslator.translate(from: codeGenerationRequest)
32+
)
33+
34+
let fileDescription = FileDescription(
35+
topComment: topComment,
36+
imports: imports,
37+
codeBlocks: codeBlocks
38+
)
39+
let fileName = String(codeGenerationRequest.fileName.split(separator: ".")[0])
40+
let file = NamedFileDescription(name: fileName, contents: fileDescription)
41+
return StructuredSwiftRepresentation(file: file)
42+
}
43+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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+
17+
/// Represents one responsibility of the ``Translator``: either the type aliases translation,
18+
/// the server code translation or the client code translation.
19+
protocol SpecializedTranslator {
20+
/// Generates an array of ``CodeBlock`` elements that will be part of the ``StructuredSwiftRepresentation`` object
21+
/// created by the ``Translator``.
22+
///
23+
/// - Parameters:
24+
/// - codeGenerationRequest: The ``CodeGenerationRequest`` object used to represent a Source IDL description of RPCs.
25+
/// - Returns: An array of ``CodeBlock`` elements.
26+
///
27+
/// - SeeAlso: ``CodeGenerationRequest``, ``Translator``, ``CodeBlock``.
28+
func translate(from codeGenerationRequest: CodeGenerationRequest) throws -> [CodeBlock]
29+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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+
17+
/// Transforms ``CodeGenerationRequest`` objects into ``StructuredSwiftRepresentation`` objects.
18+
///
19+
/// It represents the first step of the code generation process for IDL described RPCs.
20+
protocol Translator {
21+
/// Translates the provided ``CodeGenerationRequest`` object, into Swift code representation.
22+
/// - Parameters:
23+
/// - codeGenerationRequest: The IDL described RPCs representation.
24+
/// - client: Whether or not client code should be generated from the IDL described RPCs representation.
25+
/// - server: Whether or not server code should be generated from the IDL described RPCs representation.
26+
/// - Returns: A structured Swift representation of the generated code.
27+
/// - Throws: An error if there are issues translating the codeGenerationRequest.
28+
func translate(
29+
codeGenerationRequest: CodeGenerationRequest,
30+
client: Bool,
31+
server: Bool
32+
) throws -> StructuredSwiftRepresentation
33+
}

0 commit comments

Comments
 (0)