Skip to content

Commit 0bc2190

Browse files
committed
Add println which auto adds a newline at the end of each string.
The explicitly having to have a newline to end each string is what always caused hiccups when editing the generator, so this updates things to by not using `print`, it's less of an issue.
1 parent c6a5857 commit 0bc2190

File tree

8 files changed

+330
-322
lines changed

8 files changed

+330
-322
lines changed

Sources/SwiftProtobufPluginLibrary/CodePrinter.swift

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,27 @@ public struct CodePrinter {
5353
///
5454
/// - Parameter text: A variable-length list of strings to be printed.
5555
public mutating func print(_ text: String...) {
56-
printInternal(text, false)
56+
for t in text {
57+
printInternal(t, false)
58+
}
59+
}
60+
61+
/// Writes the given strings to the printer, adding a newline after
62+
/// each string. If called with no strings, a blank line is added to the
63+
/// printer.
64+
///
65+
/// Newlines within the strings are honored and indentention is applied.
66+
///
67+
/// - Parameter text: A variable-length list of strings to be printed.
68+
public mutating func println(_ text: String...) {
69+
if text.isEmpty {
70+
contentScalars.append(CodePrinter.kNewline)
71+
atLineStart = true
72+
} else {
73+
for t in text {
74+
printInternal(t, true)
75+
}
76+
}
5777
}
5878

5979
/// Indents, writes the given strings to the printer with a newline added
@@ -64,26 +84,26 @@ public struct CodePrinter {
6484
/// - Parameter text: A variable-length list of strings to be printed.
6585
public mutating func printlnIndented(_ text: String...) {
6686
indent()
67-
printInternal(text, true)
87+
for t in text {
88+
printInternal(t, true)
89+
}
6890
outdent()
6991
}
7092

7193
private static let kNewline : String.UnicodeScalarView.Element = "\n"
7294

73-
private mutating func printInternal(_ text: [String], _ newline: Bool) {
74-
for t in text {
75-
for scalar in t.unicodeScalars {
76-
// Indent at the start of a new line, unless it's a blank line.
77-
if atLineStart && scalar != CodePrinter.kNewline {
78-
contentScalars.append(contentsOf: indentation)
79-
}
80-
contentScalars.append(scalar)
81-
atLineStart = (scalar == CodePrinter.kNewline)
82-
}
83-
if newline {
84-
contentScalars.append(CodePrinter.kNewline)
85-
atLineStart = true
95+
private mutating func printInternal(_ text: String, _ newline: Bool) {
96+
for scalar in text.unicodeScalars {
97+
// Indent at the start of a new line, unless it's a blank line.
98+
if atLineStart && scalar != CodePrinter.kNewline {
99+
contentScalars.append(contentsOf: indentation)
86100
}
101+
contentScalars.append(scalar)
102+
atLineStart = (scalar == CodePrinter.kNewline)
103+
}
104+
if newline {
105+
contentScalars.append(CodePrinter.kNewline)
106+
atLineStart = true
87107
}
88108
}
89109
/// Increases the printer's indentation level.

Sources/protoc-gen-swift/EnumGenerator.swift

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -56,55 +56,59 @@ class EnumGenerator {
5656
func generateMainEnum(printer p: inout CodePrinter) {
5757
let visibility = generatorOptions.visibilitySourceSnippet
5858

59-
p.print("\n")
60-
p.print(enumDescriptor.protoSourceComments())
61-
p.print("\(visibility)enum \(swiftRelativeName): \(namer.swiftProtobufModuleName).Enum {\n")
59+
p.println(
60+
"",
61+
"\(enumDescriptor.protoSourceComments())\(visibility)enum \(swiftRelativeName): \(namer.swiftProtobufModuleName).Enum {")
6262
p.indent()
63-
p.print("\(visibility)typealias RawValue = Int\n")
63+
p.println("\(visibility)typealias RawValue = Int")
6464

6565
// Cases/aliases
6666
generateCasesOrAliases(printer: &p)
6767

6868
// Generate the default initializer.
69-
p.print("\n")
70-
p.print("\(visibility)init() {\n")
69+
p.println(
70+
"",
71+
"\(visibility)init() {")
7172
p.printlnIndented("self = \(namer.dottedRelativeName(enumValue: enumDescriptor.values.first!))")
72-
p.print("}\n")
73+
p.println("}")
7374

74-
p.print("\n")
75+
p.println()
7576
generateInitRawValue(printer: &p)
7677

77-
p.print("\n")
78+
p.println()
7879
generateRawValueProperty(printer: &p)
7980

8081
maybeGenerateCaseIterable(printer: &p)
8182

8283
p.outdent()
83-
p.print("\n")
84-
p.print("}\n")
84+
p.println(
85+
"",
86+
"}")
8587
}
8688

8789
func maybeGenerateCaseIterable(printer p: inout CodePrinter) {
8890
guard enumDescriptor.hasUnknownPreservingSemantics else { return }
8991

9092
let visibility = generatorOptions.visibilitySourceSnippet
91-
p.print("\n")
92-
p.print("// The compiler won't synthesize support with the \(unrecognizedCaseName) case.\n")
93-
p.print("\(visibility)static let allCases: [\(swiftFullName)] = [\n")
93+
p.println(
94+
"",
95+
"// The compiler won't synthesize support with the \(unrecognizedCaseName) case.",
96+
"\(visibility)static let allCases: [\(swiftFullName)] = [")
9497
for v in mainEnumValueDescriptors {
9598
let dottedName = namer.dottedRelativeName(enumValue: v)
96-
p.print(" \(dottedName),\n")
99+
p.printlnIndented("\(dottedName),")
97100
}
98-
p.print("]\n")
101+
p.println("]")
99102
}
100103

101104
func generateRuntimeSupport(printer p: inout CodePrinter) {
102-
p.print("\n")
103-
p.print("extension \(swiftFullName): \(namer.swiftProtobufModuleName)._ProtoNameProviding {\n")
105+
p.println(
106+
"",
107+
"extension \(swiftFullName): \(namer.swiftProtobufModuleName)._ProtoNameProviding {")
104108
p.indent()
105109
generateProtoNameProviding(printer: &p)
106110
p.outdent()
107-
p.print("}\n")
111+
p.println("}")
108112
}
109113

110114
/// Generates the cases or statics (for alias) for the values.
@@ -115,18 +119,18 @@ class EnumGenerator {
115119
for enumValueDescriptor in namer.uniquelyNamedValues(enum: enumDescriptor) {
116120
let comments = enumValueDescriptor.protoSourceComments()
117121
if !comments.isEmpty {
118-
p.print("\n", comments)
122+
p.println()
119123
}
120124
let relativeName = namer.relativeName(enumValue: enumValueDescriptor)
121125
if let aliasOf = enumValueDescriptor.aliasOf {
122126
let aliasOfName = namer.relativeName(enumValue: aliasOf)
123-
p.print("\(visibility)static let \(relativeName) = \(aliasOfName)\n")
127+
p.println("\(comments)\(visibility)static let \(relativeName) = \(aliasOfName)")
124128
} else {
125-
p.print("case \(relativeName) // = \(enumValueDescriptor.number)\n")
129+
p.println("\(comments)case \(relativeName) // = \(enumValueDescriptor.number)")
126130
}
127131
}
128132
if enumDescriptor.hasUnknownPreservingSemantics {
129-
p.print("case \(unrecognizedCaseName)(Int)\n")
133+
p.println("case \(unrecognizedCaseName)(Int)")
130134
}
131135
}
132136

@@ -136,18 +140,18 @@ class EnumGenerator {
136140
private func generateProtoNameProviding(printer p: inout CodePrinter) {
137141
let visibility = generatorOptions.visibilitySourceSnippet
138142

139-
p.print("\(visibility)static let _protobuf_nameMap: \(namer.swiftProtobufModuleName)._NameMap = [\n")
143+
p.println("\(visibility)static let _protobuf_nameMap: \(namer.swiftProtobufModuleName)._NameMap = [")
140144
p.indent()
141145
for v in mainEnumValueDescriptorsSorted {
142146
if v.aliases.isEmpty {
143-
p.print("\(v.number): .same(proto: \"\(v.name)\"),\n")
147+
p.println("\(v.number): .same(proto: \"\(v.name)\"),")
144148
} else {
145149
let aliasNames = v.aliases.map({ "\"\($0.name)\"" }).joined(separator: ", ")
146-
p.print("\(v.number): .aliased(proto: \"\(v.name)\", aliases: [\(aliasNames)]),\n")
150+
p.println("\(v.number): .aliased(proto: \"\(v.name)\", aliases: [\(aliasNames)]),")
147151
}
148152
}
149153
p.outdent()
150-
p.print("]\n")
154+
p.println("]")
151155
}
152156

153157
/// Generates `init?(rawValue:)` for the enum.
@@ -156,21 +160,21 @@ class EnumGenerator {
156160
private func generateInitRawValue(printer p: inout CodePrinter) {
157161
let visibility = generatorOptions.visibilitySourceSnippet
158162

159-
p.print("\(visibility)init?(rawValue: Int) {\n")
163+
p.println("\(visibility)init?(rawValue: Int) {")
160164
p.indent()
161-
p.print("switch rawValue {\n")
165+
p.println("switch rawValue {")
162166
for v in mainEnumValueDescriptorsSorted {
163167
let dottedName = namer.dottedRelativeName(enumValue: v)
164-
p.print("case \(v.number): self = \(dottedName)\n")
168+
p.println("case \(v.number): self = \(dottedName)")
165169
}
166170
if enumDescriptor.hasUnknownPreservingSemantics {
167-
p.print("default: self = .\(unrecognizedCaseName)(rawValue)\n")
171+
p.println("default: self = .\(unrecognizedCaseName)(rawValue)")
168172
} else {
169-
p.print("default: return nil\n")
173+
p.println("default: return nil")
170174
}
171-
p.print("}\n")
175+
p.println("}")
172176
p.outdent()
173-
p.print("}\n")
177+
p.println("}")
174178
}
175179

176180
/// Generates the `rawValue` property of the enum.
@@ -193,46 +197,46 @@ class EnumGenerator {
193197
(enumDescriptor.hasUnknownPreservingSemantics ? 1 : 0)
194198
let useMultipleSwitches = neededCases > maxCasesInSwitch
195199

196-
p.print("\(visibility)var rawValue: Int {\n")
200+
p.println("\(visibility)var rawValue: Int {")
197201
p.indent()
198202

199203
if useMultipleSwitches {
200204
for (i, v) in mainEnumValueDescriptorsSorted.enumerated() {
201205
if (i % maxCasesInSwitch) == 0 {
202206
if i > 0 {
203-
p.print(
204-
"default: break\n",
205-
"}\n")
207+
p.println(
208+
"default: break",
209+
"}")
206210
}
207-
p.print("switch self {\n")
211+
p.println("switch self {")
208212
}
209213
let dottedName = namer.dottedRelativeName(enumValue: v)
210-
p.print("case \(dottedName): return \(v.number)\n")
214+
p.println("case \(dottedName): return \(v.number)")
211215
}
212216
if enumDescriptor.hasUnknownPreservingSemantics {
213-
p.print("case .\(unrecognizedCaseName)(let i): return i\n")
217+
p.println("case .\(unrecognizedCaseName)(let i): return i")
214218
}
215-
p.print("""
219+
p.println("""
216220
default: break
217221
}
218222
219223
// Can't get here, all the cases are listed in the above switches.
220224
// See https://github.com/apple/swift-protobuf/issues/904 for more details.
221-
fatalError()\n
225+
fatalError()
222226
""")
223227
} else {
224-
p.print("switch self {\n")
228+
p.println("switch self {")
225229
for v in mainEnumValueDescriptorsSorted {
226230
let dottedName = namer.dottedRelativeName(enumValue: v)
227-
p.print("case \(dottedName): return \(v.number)\n")
231+
p.println("case \(dottedName): return \(v.number)")
228232
}
229233
if enumDescriptor.hasUnknownPreservingSemantics {
230-
p.print("case .\(unrecognizedCaseName)(let i): return i\n")
234+
p.println("case .\(unrecognizedCaseName)(let i): return i")
231235
}
232-
p.print("}\n")
236+
p.println("}")
233237
}
234238

235239
p.outdent()
236-
p.print("}\n")
240+
p.println("}")
237241
}
238242
}

0 commit comments

Comments
 (0)