| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- // Sources/SwiftProtobufPluginLibrary/CodePrinter.swift - Code output
- //
- // Copyright (c) 2014 - 2016 Apple Inc. and the project authors
- // Licensed under Apache License v2.0 with Runtime Library Exception
- //
- // See LICENSE.txt for license information:
- // https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
- //
- // -----------------------------------------------------------------------------
- ///
- /// This provides some basic indentation management for emitting structured
- /// source code text.
- ///
- // -----------------------------------------------------------------------------
- /// Prints code with automatic indentation based on calls to `indent` and
- /// `outdent`.
- public struct CodePrinter {
- /// Reserve an initial buffer of 64KB scalars to eliminate some reallocations
- /// in smaller files.
- private static let initialBufferSize = 65536
- /// The string content that was printed.
- public var content: String {
- return String(contentScalars)
- }
- /// See if anything was printed.
- public var isEmpty: Bool { return content.isEmpty }
- /// The Unicode scalar buffer used to build up the printed contents.
- private var contentScalars = String.UnicodeScalarView()
- /// The `UnicodeScalarView` representing a single indentation step.
- private let singleIndent: String.UnicodeScalarView
- /// The current indentation level (a collection of spaces).
- private var indentation = String.UnicodeScalarView()
- /// Keeps track of whether the printer is currently sitting at the beginning
- /// of a line.
- private var atLineStart = true
- public init(indent: String.UnicodeScalarView = " ".unicodeScalars) {
- contentScalars.reserveCapacity(CodePrinter.initialBufferSize)
- singleIndent = indent
- }
- /// Writes the given strings to the printer.
- ///
- /// - Parameter text: A variable-length list of strings to be printed.
- public mutating func print(_ text: String...) {
- for t in text {
- for scalar in t.unicodeScalars {
- // Indent at the start of a new line, unless it's a blank line.
- if atLineStart && scalar != "\n" {
- contentScalars.append(contentsOf: indentation)
- }
- contentScalars.append(scalar)
- atLineStart = (scalar == "\n")
- }
- }
- }
- /// Increases the printer's indentation level.
- public mutating func indent() {
- indentation.append(contentsOf: singleIndent)
- }
- /// Decreases the printer's indentation level.
- ///
- /// - Precondition: The printer must not have an indentation level.
- public mutating func outdent() {
- let indentCount = singleIndent.count
- precondition(indentation.count >= indentCount, "Cannot outdent past the left margin")
- indentation.removeLast(indentCount)
- }
- }
|