Skip to content

Commit 216327d

Browse files
committed
Extend how CodePrinter can be joined.
- Allow initializing off another printer to inherit state. - Add an append method that fast tracks adding to the printer.
1 parent 0bc2190 commit 216327d

File tree

3 files changed

+43
-16
lines changed

3 files changed

+43
-16
lines changed

Sources/SwiftProtobufPluginLibrary/CodePrinter.swift

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@ public struct CodePrinter {
2121
/// in smaller files.
2222
private static let initialBufferSize = 65536
2323

24+
private static let kNewline : String.UnicodeScalarView.Element = "\n"
25+
2426
/// The string content that was printed.
2527
public var content: String {
2628
return String(contentScalars)
2729
}
2830

2931
/// See if anything was printed.
30-
public var isEmpty: Bool { return content.isEmpty }
32+
public var isEmpty: Bool { return contentScalars.isEmpty }
3133

3234
/// The Unicode scalar buffer used to build up the printed contents.
3335
private var contentScalars = String.UnicodeScalarView()
@@ -42,19 +44,29 @@ public struct CodePrinter {
4244
/// of a line.
4345
private var atLineStart = true
4446

47+
/// Initialize the printer to use the give indent.
4548
public init(indent: String.UnicodeScalarView = " ".unicodeScalars) {
4649
contentScalars.reserveCapacity(CodePrinter.initialBufferSize)
4750
singleIndent = indent
4851
}
4952

53+
/// Initialize a printer using the existing indention information from
54+
/// another CodePrinter.
55+
///
56+
/// This is most useful to then use `append` to add the new content.
57+
public init(_ parent: Self) {
58+
self.init(indent: parent.singleIndent)
59+
indentation = parent.indentation
60+
}
61+
5062
/// Writes the given strings to the printer.
5163
///
5264
/// Newlines within the strings are honored and indentention is applied.
5365
///
5466
/// - Parameter text: A variable-length list of strings to be printed.
5567
public mutating func print(_ text: String...) {
5668
for t in text {
57-
printInternal(t, false)
69+
printInternal(t.unicodeScalars)
5870
}
5971
}
6072

@@ -71,7 +83,9 @@ public struct CodePrinter {
7183
atLineStart = true
7284
} else {
7385
for t in text {
74-
printInternal(t, true)
86+
printInternal(t.unicodeScalars)
87+
contentScalars.append(CodePrinter.kNewline)
88+
atLineStart = true
7589
}
7690
}
7791
}
@@ -85,27 +99,40 @@ public struct CodePrinter {
8599
public mutating func printlnIndented(_ text: String...) {
86100
indent()
87101
for t in text {
88-
printInternal(t, true)
102+
printInternal(t.unicodeScalars)
103+
contentScalars.append(CodePrinter.kNewline)
104+
atLineStart = true
89105
}
90106
outdent()
91107
}
92108

93-
private static let kNewline : String.UnicodeScalarView.Element = "\n"
94-
95-
private mutating func printInternal(_ text: String, _ newline: Bool) {
96-
for scalar in text.unicodeScalars {
109+
private mutating func printInternal(_ scalars: String.UnicodeScalarView) {
110+
for scalar in scalars {
97111
// Indent at the start of a new line, unless it's a blank line.
98112
if atLineStart && scalar != CodePrinter.kNewline {
99113
contentScalars.append(contentsOf: indentation)
100114
}
101115
contentScalars.append(scalar)
102116
atLineStart = (scalar == CodePrinter.kNewline)
103117
}
104-
if newline {
105-
contentScalars.append(CodePrinter.kNewline)
106-
atLineStart = true
118+
}
119+
120+
/// Appended the content of another `CodePrinter`to this one.
121+
///
122+
/// - Parameters:
123+
/// - printer: The other `CodePrinter` to copy from.
124+
/// - indenting: Boolean, if the text being appended should be reindented
125+
/// to the current state of this printer. If the `printer` was
126+
/// initialized off of this printer, there isn't a need to reindent.
127+
public mutating func append(_ printer: Self, indenting: Bool = false) {
128+
if indenting {
129+
printInternal(printer.contentScalars)
130+
} else {
131+
contentScalars.append(contentsOf: printer.contentScalars)
132+
atLineStart = printer.atLineStart
107133
}
108134
}
135+
109136
/// Increases the printer's indentation level.
110137
public mutating func indent() {
111138
indentation.append(contentsOf: singleIndent)

Sources/protoc-gen-swift/FileGenerator.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,14 @@ class FileGenerator {
130130
m.generateMainStruct(printer: &p, parent: nil, errorString: &errorString)
131131
}
132132

133-
var sendablePrinter = CodePrinter()
133+
var sendablePrinter = CodePrinter(p)
134134
for m in messages {
135135
m.generateSendable(printer: &sendablePrinter)
136136
}
137137

138138
if !sendablePrinter.isEmpty {
139139
p.println("", "#if swift(>=5.5) && canImport(_Concurrency)")
140-
p.print(sendablePrinter.content)
140+
p.append(sendablePrinter)
141141
p.println("#endif // swift(>=5.5) && canImport(_Concurrency)")
142142
}
143143

Sources/protoc-gen-swift/MessageGenerator.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,15 @@ class MessageGenerator {
170170
}
171171
p.println("\(storage.storageVisibility) var _storage = _StorageClass.defaultInstance")
172172
} else {
173-
var subMessagePrinter = CodePrinter()
173+
var subMessagePrinter = CodePrinter(p)
174174
for f in fields {
175175
f.generateStorage(printer: &subMessagePrinter)
176176
}
177177
if !subMessagePrinter.isEmpty {
178178
if !isExtensible {
179179
p.println()
180180
}
181-
p.print(subMessagePrinter.content)
181+
p.append(subMessagePrinter)
182182
}
183183
}
184184

@@ -451,7 +451,7 @@ class MessageGenerator {
451451
}
452452
if generatedChecks {
453453
generateWithLifetimeExtension(printer: &p, returns: true) { p in
454-
p.print(fieldCheckPrinter.content)
454+
p.append(fieldCheckPrinter, indenting: true)
455455
p.println("return true")
456456
}
457457
} else {

0 commit comments

Comments
 (0)