@@ -217,6 +217,8 @@ class MessageGenerator {
217
217
// generateIsInitialized provides a blank line after itself.
218
218
generateDecodeMessage ( printer: & p)
219
219
p. print ( )
220
+ generateFieldNodes ( printer: & p)
221
+ p. print ( )
220
222
generateTraverse ( printer: & p)
221
223
p. print ( )
222
224
generateMessageEquality ( printer: & p)
@@ -311,53 +313,53 @@ class MessageGenerator {
311
313
p. print ( " } " )
312
314
}
313
315
}
314
-
315
316
}
316
317
}
317
318
p. print ( " } " )
318
319
}
319
320
320
- /// Generates the `traverse` method for the message.
321
- ///
322
- /// - Parameter p: The code printer.
323
- private func generateTraverse( printer p: inout CodePrinter ) {
324
- p. print ( " \( visibility) func traverse<V: \( namer. swiftProtobufModulePrefix) Visitor>(visitor: inout V) throws { " )
325
- p. withIndentation { p in
326
- generateWithLifetimeExtension ( printer: & p, throws: true ) { p in
327
- if let storage = storage {
328
- storage. generatePreTraverse ( printer: & p)
329
- }
321
+ private func generateFieldNodes( printer p: inout CodePrinter ) {
322
+ let visitExtensionsName = descriptor. useMessageSetWireFormat ? " extensionFieldsAsMessageSet " : " extensionFields "
330
323
331
- let visitExtensionsName =
332
- descriptor. useMessageSetWireFormat ? " visitExtensionFieldsAsMessageSet " : " visitExtensionFields "
333
-
334
- let usesLocals = fields. reduce ( false ) { $0 || $1. generateTraverseUsesLocals }
335
- if usesLocals {
336
- p. print ( """
337
- // The use of inline closures is to circumvent an issue where the compiler
338
- // allocates stack space for every if/case branch local when no optimizations
339
- // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
340
- // https://github.com/apple/swift-protobuf/issues/1182
341
- """ )
342
- }
324
+ p. print ( " \( visibility) static let _fields: [Field<Self>] = [ " )
325
+
326
+ // Use the "ambitious" ranges because for visit because subranges with no
327
+ // intermixed fields can be merged to reduce the number of calls for
328
+ // extension visitation.
329
+ var ranges = descriptor. ambitiousExtensionRanges. makeIterator ( )
330
+ var nextRange = ranges. next ( )
343
331
344
- // Use the "ambitious" ranges because for visit because subranges with no
345
- // intermixed fields can be merged to reduce the number of calls for
346
- // extension visitation.
347
- var ranges = descriptor. ambitiousExtensionRanges. makeIterator ( )
348
- var nextRange = ranges. next ( )
349
- for f in fieldsSortedByNumber {
350
- while nextRange != nil && Int ( nextRange!. lowerBound) < f. number {
351
- p. print ( " try visitor. \( visitExtensionsName) (fields: _protobuf_extensionFieldValues, start: \( nextRange!. lowerBound) , end: \( nextRange!. upperBound) ) " )
352
- nextRange = ranges. next ( )
353
- }
354
- f. generateTraverse ( printer: & p)
355
- }
356
- while nextRange != nil {
357
- p. print ( " try visitor. \( visitExtensionsName) (fields: _protobuf_extensionFieldValues, start: \( nextRange!. lowerBound) , end: \( nextRange!. upperBound) ) " )
332
+ p. withIndentation { p in
333
+ for f in fieldsSortedByNumber {
334
+ while nextRange != nil && Int ( nextRange!. lowerBound) < f. number {
335
+ p. print ( " . \( visitExtensionsName) ({ $0._protobuf_extensionFieldValues }, start: \( nextRange!. lowerBound) , end: \( nextRange!. upperBound) ), " )
358
336
nextRange = ranges. next ( )
359
337
}
338
+ f. generateFieldNode ( printer: & p)
339
+ }
340
+ while nextRange != nil {
341
+ p. print ( " . \( visitExtensionsName) ({ $0._protobuf_extensionFieldValues }, start: \( nextRange!. lowerBound) , end: \( nextRange!. upperBound) ), " )
342
+ nextRange = ranges. next ( )
360
343
}
344
+ }
345
+ p. print ( " ] " )
346
+
347
+ for oneof in oneofs {
348
+ oneof. generateFieldNodeStaticLet ( printer: & p)
349
+ }
350
+ }
351
+
352
+ private func generateTraverse( printer p: inout CodePrinter ) {
353
+ // If we have an AnyMessageStorageClass we need to generate the traverse function so it can include a preTraverse call
354
+ guard let storage, storage is AnyMessageStorageClassGenerator else {
355
+ return
356
+ }
357
+ p. print ( " \( visibility) func traverse<V: Visitor>(visitor: inout V) throws { " )
358
+ p. withIndentation { p in
359
+ p. print ( " try _storage.preTraverse() " )
360
+ p. print ( " for field in Self._fields { " )
361
+ p. printIndented ( " try field.traverse(message: self, visitor: &visitor) " )
362
+ p. print ( " } " )
361
363
p. print ( " try unknownFields.traverse(visitor: &visitor) " )
362
364
}
363
365
p. print ( " } " )
0 commit comments