Google_Protobuf_SourceCodeInfo+Extensions.swift 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Sources/SwiftProtobufPluginLibrary/Google_Protobuf_SourceCodeInfo+Extensions.swift - SourceCodeInfo Additions
  2. //
  3. // Copyright (c) 2014 - 2017 Apple Inc. and the project authors
  4. // Licensed under Apache License v2.0 with Runtime Library Exception
  5. //
  6. // See LICENSE.txt for license information:
  7. // https://github.com/apple/swift-protobuf/blob/main/LICENSE.txt
  8. //
  9. // -----------------------------------------------------------------------------
  10. import Foundation
  11. import SwiftProtobuf
  12. extension Google_Protobuf_SourceCodeInfo.Location {
  13. /// Builds a source comment out of the location's comment fields.
  14. ///
  15. /// If leadingDetachedPrefix is not provided, those comments won't
  16. /// be collected.
  17. public func asSourceComment(commentPrefix: String,
  18. leadingDetachedPrefix: String? = nil) -> String {
  19. func escapeMarkup(_ text: String) -> String {
  20. // Proto file comments don't really have any markup associated with
  21. // them. Swift uses something like MarkDown:
  22. // "Markup Formatting Reference"
  23. // https://developer.apple.com/library/content/documentation/Xcode/Reference/xcode_markup_formatting_ref/index.html
  24. // Sadly that format doesn't really lend itself to any form of
  25. // escaping to ensure comments are interpreted markup when they
  26. // really aren't. About the only thing that could be done is to
  27. // try and escape some set of things that could start directives,
  28. // and that gets pretty chatty/ugly pretty quickly.
  29. return text
  30. }
  31. func prefixLines(text: String, prefix: String) -> String {
  32. var result = String()
  33. // Protoc doesn't normalize newlines in the comments, make sure CRLF
  34. // doesn't insert blank lines and the generated file is hopefully then
  35. // consistent in using '\n'.
  36. var lines =
  37. text.replacingOccurrences(of: "\r\n", with: "\n").components(separatedBy: .newlines)
  38. // Trim any blank lines off the end.
  39. while !lines.isEmpty && lines.last!.trimmingCharacters(in: .whitespaces).isEmpty {
  40. lines.removeLast()
  41. }
  42. for line in lines {
  43. result.append(prefix + line + "\n")
  44. }
  45. return result
  46. }
  47. var result = String()
  48. if let leadingDetachedPrefix = leadingDetachedPrefix {
  49. for detached in leadingDetachedComments {
  50. let comment = prefixLines(text: detached, prefix: leadingDetachedPrefix)
  51. if !comment.isEmpty {
  52. result += comment
  53. // Detached comments have blank lines between then (and
  54. // anything that follows them).
  55. result += "\n"
  56. }
  57. }
  58. }
  59. let comments = hasLeadingComments ? leadingComments : trailingComments
  60. result += prefixLines(text: escapeMarkup(comments), prefix: commentPrefix)
  61. return result
  62. }
  63. }