Descriptor+Extensions.swift 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. // Sources/SwiftProtobufPluginLibrary/Descriptor+Extensions.swift - Additions to Descriptor
  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 FileDescriptor: ProvidesSourceCodeLocation {
  13. public var sourceCodeInfoLocation: Google_Protobuf_SourceCodeInfo.Location? {
  14. // google/protobuf's descriptor.cc says it should be an empty path.
  15. sourceCodeInfoLocation(path: IndexPath())
  16. }
  17. }
  18. extension Descriptor: ProvidesLocationPath, ProvidesSourceCodeLocation, TypeOrFileProvidesDeprecationComment {
  19. public func getLocationPath(path: inout IndexPath) {
  20. if let containingType = containingType {
  21. containingType.getLocationPath(path: &path)
  22. path.append(Google_Protobuf_DescriptorProto.FieldNumbers.nestedType)
  23. } else {
  24. path.append(Google_Protobuf_FileDescriptorProto.FieldNumbers.messageType)
  25. }
  26. path.append(index)
  27. }
  28. public var typeName: String { "message" }
  29. public var isDeprecated: Bool { options.deprecated }
  30. }
  31. extension Descriptor.ExtensionRange: ProvidesLocationPath, ProvidesSourceCodeLocation {
  32. public func getLocationPath(path: inout IndexPath) {
  33. containingType.getLocationPath(path: &path)
  34. path.append(Google_Protobuf_DescriptorProto.FieldNumbers.extensionRange)
  35. path.append(index)
  36. }
  37. }
  38. extension EnumDescriptor: ProvidesLocationPath, ProvidesSourceCodeLocation, TypeOrFileProvidesDeprecationComment {
  39. public func getLocationPath(path: inout IndexPath) {
  40. if let containingType = containingType {
  41. containingType.getLocationPath(path: &path)
  42. path.append(Google_Protobuf_DescriptorProto.FieldNumbers.enumType)
  43. } else {
  44. path.append(Google_Protobuf_FileDescriptorProto.FieldNumbers.enumType)
  45. }
  46. path.append(index)
  47. }
  48. public var typeName: String { "enum" }
  49. public var isDeprecated: Bool { options.deprecated }
  50. }
  51. extension EnumValueDescriptor: ProvidesLocationPath, ProvidesSourceCodeLocation, SimpleProvidesDeprecationComment {
  52. public func getLocationPath(path: inout IndexPath) {
  53. enumType.getLocationPath(path: &path)
  54. path.append(Google_Protobuf_EnumDescriptorProto.FieldNumbers.value)
  55. path.append(index)
  56. }
  57. public var typeName: String { "enum value" }
  58. public var isDeprecated: Bool { options.deprecated }
  59. }
  60. extension OneofDescriptor: ProvidesLocationPath, ProvidesSourceCodeLocation {
  61. public func getLocationPath(path: inout IndexPath) {
  62. containingType.getLocationPath(path: &path)
  63. path.append(Google_Protobuf_DescriptorProto.FieldNumbers.oneofDecl)
  64. path.append(index)
  65. }
  66. }
  67. extension FieldDescriptor: ProvidesLocationPath, ProvidesSourceCodeLocation, ProvidesDeprecationComment {
  68. public func getLocationPath(path: inout IndexPath) {
  69. if isExtension {
  70. if let extensionScope = extensionScope {
  71. extensionScope.getLocationPath(path: &path)
  72. path.append(Google_Protobuf_DescriptorProto.FieldNumbers.extension)
  73. } else {
  74. path.append(Google_Protobuf_FileDescriptorProto.FieldNumbers.extension)
  75. }
  76. } else {
  77. containingType.getLocationPath(path: &path)
  78. path.append(Google_Protobuf_DescriptorProto.FieldNumbers.field)
  79. }
  80. path.append(index)
  81. }
  82. public func deprecationComment(commentPrefix: String) -> String {
  83. // FieldDesciptor can be an extension field or a normal field, so it needs
  84. // a custom imply to only look at the file for extentsion fields.
  85. if options.deprecated {
  86. return
  87. "\(commentPrefix) NOTE: This \(isExtension ? "extension field" : "field") was marked as deprecated in the .proto file.\n"
  88. }
  89. if isExtension && file.options.deprecated {
  90. return
  91. "\(commentPrefix) NOTE: The whole .proto file that defined this extension field was marked as deprecated.\n"
  92. }
  93. return String()
  94. }
  95. /// Returns true if the type can be used for a Packed field.
  96. static func isPackable(type: Google_Protobuf_FieldDescriptorProto.TypeEnum) -> Bool {
  97. // This logic comes from the C++ FieldDescriptor::IsTypePackable() impl.
  98. switch type {
  99. case .string, .group, .message, .bytes:
  100. return false
  101. default:
  102. return true
  103. }
  104. }
  105. /// Helper to return the name to as the "base" for naming of generated fields.
  106. ///
  107. /// Groups use the underlying message's name. The way groups are declared in
  108. /// proto files, the filed names is derived by lowercasing the Group's name,
  109. /// so there are no underscores, etc. to rebuild a camel case name from.
  110. var namingBase: String { isGroupLike ? messageType!.name : name }
  111. /// TODO: Remove this when it is safe to make breaking changes.
  112. @available(*, deprecated, message: "Please open a GitHub issue if you think functionality is missing.")
  113. public var internal_isGroupLike: Bool { isGroupLike }
  114. /// Helper to see if this is "group-like". Edition 2024 will likely provide
  115. /// a new feature to better deal with this. See upsteam protobuf for more
  116. /// details on the problem.
  117. ///
  118. /// This models upstream internal::cpp::IsGroupLike().
  119. package var isGroupLike: Bool {
  120. guard type == .group else {
  121. return false
  122. }
  123. // `messageType` can't realy be nil once we know it's a group.
  124. let messageType = messageType!
  125. // The original proto2 syntax concept of a group always has a field name
  126. // that is the exact lowercasing of the message name.
  127. guard name == messageType.name.lowercased() else {
  128. return false
  129. }
  130. // The message defined by a group is at the same scope as the field. So...
  131. if isExtension {
  132. if extensionScope == nil {
  133. // Top level extension, so the message made by the group has to be the
  134. // same file and also a type level type.
  135. return messageType.file === file && messageType.containingType == nil
  136. } else {
  137. // Extension field was scoped to a message, so the group will be also
  138. // nested under that same message.
  139. return messageType.containingType === extensionScope
  140. }
  141. } else {
  142. // A regular message field, the message made by the group has to be
  143. // nested under this same message.
  144. return messageType.containingType === containingType
  145. }
  146. }
  147. }
  148. extension ServiceDescriptor: ProvidesLocationPath, ProvidesSourceCodeLocation, TypeOrFileProvidesDeprecationComment {
  149. public func getLocationPath(path: inout IndexPath) {
  150. path.append(Google_Protobuf_FileDescriptorProto.FieldNumbers.service)
  151. path.append(index)
  152. }
  153. public var typeName: String { "service" }
  154. public var isDeprecated: Bool { options.deprecated }
  155. }
  156. extension MethodDescriptor: ProvidesLocationPath, ProvidesSourceCodeLocation, SimpleProvidesDeprecationComment {
  157. public func getLocationPath(path: inout IndexPath) {
  158. service.getLocationPath(path: &path)
  159. path.append(Google_Protobuf_ServiceDescriptorProto.FieldNumbers.method)
  160. path.append(index)
  161. }
  162. public var typeName: String { "method" }
  163. public var isDeprecated: Bool { options.deprecated }
  164. }