From c5b3769865d6f9381f7e1feb906a89118b2451af Mon Sep 17 00:00:00 2001 From: Thomas Van Lenten Date: Thu, 8 Sep 2022 12:04:00 -0400 Subject: [PATCH] Move the two extension range helpers out of Descriptor. These two apis aren't a normal part of the C++ Descriptor api, so move them out to the plugin level itself so they aren't public api going forward. As of http://github.com/apple/swift-package-manager/pull/3316 tests can depend on executable targets. The majority of this CL is then adding a new test (only for newer SwiftPM versions) that allows the tests also to have been moved over. --- .gitignore | 2 +- Makefile | 40 +- Package.swift | 4 + Protos/plugin_descriptor_test.proto | 63 +++ Protos/pluginlib_descriptor_test.proto | 44 --- Reference/plugin_descriptor_test.pb.swift | 363 ++++++++++++++++++ Reference/pluginlib_descriptor_test.pb.swift | 319 --------------- .../Descriptor.swift | 58 --- .../Descriptor+Extensions.swift | 65 +++- .../protoc-gen-swift/MessageGenerator.swift | 7 +- .../protoc-gen-swift/Range+Extensions.swift | 26 ++ .../DescriptorTestData.swift | 357 ++++++++--------- .../Test_Descriptor.swift | 99 ----- .../DescriptorTestData.swift | 54 +++ .../Test_DescriptorExtensions.swift | 117 ++++++ 15 files changed, 871 insertions(+), 747 deletions(-) create mode 100644 Protos/plugin_descriptor_test.proto create mode 100644 Reference/plugin_descriptor_test.pb.swift create mode 100644 Tests/protoc-gen-swiftTests/DescriptorTestData.swift create mode 100644 Tests/protoc-gen-swiftTests/Test_DescriptorExtensions.swift diff --git a/.gitignore b/.gitignore index 929c2ba51..ca945412f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ xcbaselines /docs /build mined_words.txt -/DescriptorTestData.bin +/*DescriptorTestData.bin /Package.resolved # Intermediate conformance test outputs diff --git a/Makefile b/Makefile index f9f15d71b..f58118a39 100644 --- a/Makefile +++ b/Makefile @@ -164,11 +164,14 @@ CONFORMANCE_PROTOS= \ Protos/google/protobuf/test_messages_proto2.proto \ Protos/google/protobuf/test_messages_proto3.proto -SWIFT_DESCRIPTOR_TEST_PROTOS= \ +SWIFT_PLUGINLIB_DESCRIPTOR_TEST_PROTOS= \ Protos/pluginlib_descriptor_test.proto \ Protos/pluginlib_descriptor_test2.proto \ ${PLUGIN_PROTOS} +SWIFT_PLUGIN_DESCRIPTOR_TEST_PROTOS= \ + Protos/plugin_descriptor_test.proto + .PHONY: \ all \ build \ @@ -200,8 +203,13 @@ all: build # This generates a LinuxMain.swift to include all of the test cases. # It is needed for all builds before 5.4.x +# NOTE: This doesn't include Tests/protoc-gen-swiftTests because the older +# SwiftPM versions could have a test depend on an executable target. generate-linux-main: - @${AWK} -f DevTools/CollectTests.awk Tests/*/Test_*.swift > Tests/LinuxMain.swift.new + @${AWK} -f DevTools/CollectTests.awk \ + Tests/SwiftProtobufPluginLibraryTests/Test_*.swift \ + Tests/SwiftProtobufTests/Test_*.swift \ + > Tests/LinuxMain.swift.new @if ! cmp -s Tests/LinuxMain.swift.new Tests/LinuxMain.swift; then \ cp Tests/LinuxMain.swift.new Tests/LinuxMain.swift; \ echo "FYI: Tests/LinuxMain.swift Updated"; \ @@ -222,7 +230,7 @@ install: build clean: swift package clean - rm -rf .build _test ${PROTOC_GEN_SWIFT} DescriptorTestData.bin \ + rm -rf .build _test ${PROTOC_GEN_SWIFT} *DescriptorTestData.bin \ Performance/_generated Performance/_results Protos/mined_words.txt \ docs build find . -name '*~' | xargs rm -f @@ -313,6 +321,7 @@ regenerate: \ regenerate-plugin-protos \ regenerate-test-protos \ regenerate-conformance-protos \ + Tests/protoc-gen-swiftTests/DescriptorTestData.swift \ Tests/SwiftProtobufPluginLibraryTests/DescriptorTestData.swift # Rebuild just the protos included in the runtime library @@ -353,20 +362,37 @@ regenerate-fuzz-protos: build ${PROTOC_GEN_SWIFT} --tfiws_out=FuzzTesting/Sources/FuzzCommon \ Protos/fuzz_testing.proto -Tests/SwiftProtobufPluginLibraryTests/DescriptorTestData.swift: build ${PROTOC_GEN_SWIFT} ${SWIFT_DESCRIPTOR_TEST_PROTOS} +Tests/SwiftProtobufPluginLibraryTests/DescriptorTestData.swift: build ${PROTOC_GEN_SWIFT} ${SWIFT_PLUGINLIB_DESCRIPTOR_TEST_PROTOS} + # Until the flag isn't needed, add the flag to enable proto3 optional. + @${PROTOC} \ + --experimental_allow_proto3_optional \ + --include_imports \ + --descriptor_set_out=PluginLibDescriptorTestData.bin \ + -I Protos \ + ${SWIFT_PLUGINLIB_DESCRIPTOR_TEST_PROTOS} + @rm -f $@ + @echo '// See Makefile how this is generated.' >> $@ + @echo '// swift-format-ignore-file' >> $@ + @echo 'import Foundation' >> $@ + @echo 'let fileDescriptorSetBytes: [UInt8] = [' >> $@ + @xxd -i < PluginLibDescriptorTestData.bin >> $@ + @echo ']' >> $@ + @echo 'let fileDescriptorSetData = Data(fileDescriptorSetBytes)' >> $@ + +Tests/protoc-gen-swiftTests/DescriptorTestData.swift: build ${PROTOC_GEN_SWIFT} ${SWIFT_PLUGIN_DESCRIPTOR_TEST_PROTOS} # Until the flag isn't needed, add the flag to enable proto3 optional. @${PROTOC} \ --experimental_allow_proto3_optional \ --include_imports \ - --descriptor_set_out=DescriptorTestData.bin \ + --descriptor_set_out=PluginDescriptorTestData.bin \ -I Protos \ - ${SWIFT_DESCRIPTOR_TEST_PROTOS} + ${SWIFT_PLUGIN_DESCRIPTOR_TEST_PROTOS} @rm -f $@ @echo '// See Makefile how this is generated.' >> $@ @echo '// swift-format-ignore-file' >> $@ @echo 'import Foundation' >> $@ @echo 'let fileDescriptorSetBytes: [UInt8] = [' >> $@ - @xxd -i < DescriptorTestData.bin >> $@ + @xxd -i < PluginDescriptorTestData.bin >> $@ @echo ']' >> $@ @echo 'let fileDescriptorSetData = Data(fileDescriptorSetBytes)' >> $@ diff --git a/Package.swift b/Package.swift index 28f05246b..ed9290e76 100644 --- a/Package.swift +++ b/Package.swift @@ -69,6 +69,10 @@ let package = Package( name: "SwiftProtobufPluginLibraryTests", dependencies: ["SwiftProtobufPluginLibrary"] ), + .testTarget( + name: "protoc-gen-swiftTests", + dependencies: ["protoc-gen-swift"] + ), ], swiftLanguageVersions: [.v5] ) diff --git a/Protos/plugin_descriptor_test.proto b/Protos/plugin_descriptor_test.proto new file mode 100644 index 000000000..d46ade2e4 --- /dev/null +++ b/Protos/plugin_descriptor_test.proto @@ -0,0 +1,63 @@ +// Protos/pluginlib_descriptor_test.proto - test proto +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +// ----------------------------------------------------------------------------- +/// +/// Test proto for Tests/SwiftProtobufPluginLibraryTests/Test_Descriptor.swift +/// +// ----------------------------------------------------------------------------- + +syntax = "proto2"; + +package swift_descriptor_test; + +// To check handling of extension ranges that are out of order. +message MsgExtensionRangeOrdering { + extensions 1, 3, 2, 4; + extensions 7; + reserved 8; + extensions 9; + + extensions 100 to 110; + reserved 121 to 125; + extensions 126 to 130; + extensions 111 to 120; +} + +// To check handling of extension ranges that are out of order, have fields or +// reserved things mix through them. +message MsgExtensionRangeOrderingWithFields { + extensions 1, 3, 2, 4; + optional int32 field6 = 6; + extensions 7; + reserved 8; + extensions 9; + + extensions 100 to 110; + reserved 121 to 123; + optional int32 field124 = 124; + optional int32 field125 = 125; + extensions 126 to 130; + extensions 111 to 120; + optional int32 field200 = 200; +} + +// Intermixed ranges and fields so help ensure no merge issues +message MsgExtensionRangeOrderingNoMerging { + optional int32 field1 = 1; + optional int32 field2 = 2; + extensions 3 to 5; + optional int32 field6 = 6; + extensions 7 to 12; + optional int32 field13 = 13; + optional int32 field15 = 15; + extensions 16 to 20; + optional int32 field21 = 21; +} diff --git a/Protos/pluginlib_descriptor_test.proto b/Protos/pluginlib_descriptor_test.proto index cf0340087..05f6b8217 100644 --- a/Protos/pluginlib_descriptor_test.proto +++ b/Protos/pluginlib_descriptor_test.proto @@ -106,47 +106,3 @@ message Proto2MessageForPresence { } } - -// To check handling of extension ranges that are out of order. -message MsgExtensionRangeOrdering { - extensions 1, 3, 2, 4; - extensions 7; - reserved 8; - extensions 9; - - extensions 100 to 110; - reserved 121 to 125; - extensions 126 to 130; - extensions 111 to 120; -} - -// To check handling of extension ranges that are out of order, have fields or -// reserved things mix through them. -message MsgExtensionRangeOrderingWithFields { - extensions 1, 3, 2, 4; - optional int32 field6 = 6; - extensions 7; - reserved 8; - extensions 9; - - extensions 100 to 110; - reserved 121 to 123; - optional int32 field124 = 124; - optional int32 field125 = 125; - extensions 126 to 130; - extensions 111 to 120; - optional int32 field200 = 200; -} - -// Intermixed ranges and fields so help ensure no merge issues -message MsgExtensionRangeOrderingNoMerging { - optional int32 field1 = 1; - optional int32 field2 = 2; - extensions 3 to 5; - optional int32 field6 = 6; - extensions 7 to 12; - optional int32 field13 = 13; - optional int32 field15 = 15; - extensions 16 to 20; - optional int32 field21 = 21; -} diff --git a/Reference/plugin_descriptor_test.pb.swift b/Reference/plugin_descriptor_test.pb.swift new file mode 100644 index 000000000..5881be78e --- /dev/null +++ b/Reference/plugin_descriptor_test.pb.swift @@ -0,0 +1,363 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: plugin_descriptor_test.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Protos/pluginlib_descriptor_test.proto - test proto +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +// ----------------------------------------------------------------------------- +/// +/// Test proto for Tests/SwiftProtobufPluginLibraryTests/Test_Descriptor.swift +/// +// ----------------------------------------------------------------------------- + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _3: SwiftProtobuf.ProtobufAPIVersion_3 {} + typealias Version = _3 +} + +/// To check handling of extension ranges that are out of order. +struct SwiftDescriptorTest_MsgExtensionRangeOrdering: SwiftProtobuf.ExtensibleMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() +} + +/// To check handling of extension ranges that are out of order, have fields or +/// reserved things mix through them. +struct SwiftDescriptorTest_MsgExtensionRangeOrderingWithFields: SwiftProtobuf.ExtensibleMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var field6: Int32 { + get {return _field6 ?? 0} + set {_field6 = newValue} + } + /// Returns true if `field6` has been explicitly set. + var hasField6: Bool {return self._field6 != nil} + /// Clears the value of `field6`. Subsequent reads from it will return its default value. + mutating func clearField6() {self._field6 = nil} + + var field124: Int32 { + get {return _field124 ?? 0} + set {_field124 = newValue} + } + /// Returns true if `field124` has been explicitly set. + var hasField124: Bool {return self._field124 != nil} + /// Clears the value of `field124`. Subsequent reads from it will return its default value. + mutating func clearField124() {self._field124 = nil} + + var field125: Int32 { + get {return _field125 ?? 0} + set {_field125 = newValue} + } + /// Returns true if `field125` has been explicitly set. + var hasField125: Bool {return self._field125 != nil} + /// Clears the value of `field125`. Subsequent reads from it will return its default value. + mutating func clearField125() {self._field125 = nil} + + var field200: Int32 { + get {return _field200 ?? 0} + set {_field200 = newValue} + } + /// Returns true if `field200` has been explicitly set. + var hasField200: Bool {return self._field200 != nil} + /// Clears the value of `field200`. Subsequent reads from it will return its default value. + mutating func clearField200() {self._field200 = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() + fileprivate var _field6: Int32? = nil + fileprivate var _field124: Int32? = nil + fileprivate var _field125: Int32? = nil + fileprivate var _field200: Int32? = nil +} + +/// Intermixed ranges and fields so help ensure no merge issues +struct SwiftDescriptorTest_MsgExtensionRangeOrderingNoMerging: SwiftProtobuf.ExtensibleMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var field1: Int32 { + get {return _field1 ?? 0} + set {_field1 = newValue} + } + /// Returns true if `field1` has been explicitly set. + var hasField1: Bool {return self._field1 != nil} + /// Clears the value of `field1`. Subsequent reads from it will return its default value. + mutating func clearField1() {self._field1 = nil} + + var field2: Int32 { + get {return _field2 ?? 0} + set {_field2 = newValue} + } + /// Returns true if `field2` has been explicitly set. + var hasField2: Bool {return self._field2 != nil} + /// Clears the value of `field2`. Subsequent reads from it will return its default value. + mutating func clearField2() {self._field2 = nil} + + var field6: Int32 { + get {return _field6 ?? 0} + set {_field6 = newValue} + } + /// Returns true if `field6` has been explicitly set. + var hasField6: Bool {return self._field6 != nil} + /// Clears the value of `field6`. Subsequent reads from it will return its default value. + mutating func clearField6() {self._field6 = nil} + + var field13: Int32 { + get {return _field13 ?? 0} + set {_field13 = newValue} + } + /// Returns true if `field13` has been explicitly set. + var hasField13: Bool {return self._field13 != nil} + /// Clears the value of `field13`. Subsequent reads from it will return its default value. + mutating func clearField13() {self._field13 = nil} + + var field15: Int32 { + get {return _field15 ?? 0} + set {_field15 = newValue} + } + /// Returns true if `field15` has been explicitly set. + var hasField15: Bool {return self._field15 != nil} + /// Clears the value of `field15`. Subsequent reads from it will return its default value. + mutating func clearField15() {self._field15 = nil} + + var field21: Int32 { + get {return _field21 ?? 0} + set {_field21 = newValue} + } + /// Returns true if `field21` has been explicitly set. + var hasField21: Bool {return self._field21 != nil} + /// Clears the value of `field21`. Subsequent reads from it will return its default value. + mutating func clearField21() {self._field21 = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() + fileprivate var _field1: Int32? = nil + fileprivate var _field2: Int32? = nil + fileprivate var _field6: Int32? = nil + fileprivate var _field13: Int32? = nil + fileprivate var _field15: Int32? = nil + fileprivate var _field21: Int32? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension SwiftDescriptorTest_MsgExtensionRangeOrdering: @unchecked Sendable {} +extension SwiftDescriptorTest_MsgExtensionRangeOrderingWithFields: @unchecked Sendable {} +extension SwiftDescriptorTest_MsgExtensionRangeOrderingNoMerging: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "swift_descriptor_test" + +extension SwiftDescriptorTest_MsgExtensionRangeOrdering: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".MsgExtensionRangeOrdering" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + public var isInitialized: Bool { + if !_protobuf_extensionFieldValues.isInitialized {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1..<5, 7, 9, 100..<121, 126..<131: + try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: SwiftDescriptorTest_MsgExtensionRangeOrdering.self, fieldNumber: fieldNumber) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1, end: 131) + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: SwiftDescriptorTest_MsgExtensionRangeOrdering, rhs: SwiftDescriptorTest_MsgExtensionRangeOrdering) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} + return true + } +} + +extension SwiftDescriptorTest_MsgExtensionRangeOrderingWithFields: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".MsgExtensionRangeOrderingWithFields" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 6: .same(proto: "field6"), + 124: .same(proto: "field124"), + 125: .same(proto: "field125"), + 200: .same(proto: "field200"), + ] + + public var isInitialized: Bool { + if !_protobuf_extensionFieldValues.isInitialized {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 6: try { try decoder.decodeSingularInt32Field(value: &self._field6) }() + case 124: try { try decoder.decodeSingularInt32Field(value: &self._field124) }() + case 125: try { try decoder.decodeSingularInt32Field(value: &self._field125) }() + case 200: try { try decoder.decodeSingularInt32Field(value: &self._field200) }() + case 1..<5, 7, 9, 100..<121, 126..<131: + try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: SwiftDescriptorTest_MsgExtensionRangeOrderingWithFields.self, fieldNumber: fieldNumber) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1, end: 5) + try { if let v = self._field6 { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 6) + } }() + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 7, end: 121) + try { if let v = self._field124 { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 124) + } }() + try { if let v = self._field125 { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 125) + } }() + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 126, end: 131) + try { if let v = self._field200 { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 200) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: SwiftDescriptorTest_MsgExtensionRangeOrderingWithFields, rhs: SwiftDescriptorTest_MsgExtensionRangeOrderingWithFields) -> Bool { + if lhs._field6 != rhs._field6 {return false} + if lhs._field124 != rhs._field124 {return false} + if lhs._field125 != rhs._field125 {return false} + if lhs._field200 != rhs._field200 {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} + return true + } +} + +extension SwiftDescriptorTest_MsgExtensionRangeOrderingNoMerging: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".MsgExtensionRangeOrderingNoMerging" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "field1"), + 2: .same(proto: "field2"), + 6: .same(proto: "field6"), + 13: .same(proto: "field13"), + 15: .same(proto: "field15"), + 21: .same(proto: "field21"), + ] + + public var isInitialized: Bool { + if !_protobuf_extensionFieldValues.isInitialized {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self._field1) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self._field2) }() + case 6: try { try decoder.decodeSingularInt32Field(value: &self._field6) }() + case 13: try { try decoder.decodeSingularInt32Field(value: &self._field13) }() + case 15: try { try decoder.decodeSingularInt32Field(value: &self._field15) }() + case 21: try { try decoder.decodeSingularInt32Field(value: &self._field21) }() + case 3..<6, 7..<13, 16..<21: + try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: SwiftDescriptorTest_MsgExtensionRangeOrderingNoMerging.self, fieldNumber: fieldNumber) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._field1 { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) + } }() + try { if let v = self._field2 { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) + } }() + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 3, end: 6) + try { if let v = self._field6 { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 6) + } }() + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 7, end: 13) + try { if let v = self._field13 { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 13) + } }() + try { if let v = self._field15 { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 15) + } }() + try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 16, end: 21) + try { if let v = self._field21 { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 21) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: SwiftDescriptorTest_MsgExtensionRangeOrderingNoMerging, rhs: SwiftDescriptorTest_MsgExtensionRangeOrderingNoMerging) -> Bool { + if lhs._field1 != rhs._field1 {return false} + if lhs._field2 != rhs._field2 {return false} + if lhs._field6 != rhs._field6 {return false} + if lhs._field13 != rhs._field13 {return false} + if lhs._field15 != rhs._field15 {return false} + if lhs._field21 != rhs._field21 {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} + return true + } +} diff --git a/Reference/pluginlib_descriptor_test.pb.swift b/Reference/pluginlib_descriptor_test.pb.swift index 2ca1ee02a..fc3c0fac4 100644 --- a/Reference/pluginlib_descriptor_test.pb.swift +++ b/Reference/pluginlib_descriptor_test.pb.swift @@ -419,146 +419,6 @@ struct SDTProto2MessageForPresence { fileprivate var _optMessageField: SDTTopLevelMessage? = nil } -/// To check handling of extension ranges that are out of order. -struct SDTMsgExtensionRangeOrdering: SwiftProtobuf.ExtensibleMessage { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() -} - -/// To check handling of extension ranges that are out of order, have fields or -/// reserved things mix through them. -struct SDTMsgExtensionRangeOrderingWithFields: SwiftProtobuf.ExtensibleMessage { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var field6: Int32 { - get {return _field6 ?? 0} - set {_field6 = newValue} - } - /// Returns true if `field6` has been explicitly set. - var hasField6: Bool {return self._field6 != nil} - /// Clears the value of `field6`. Subsequent reads from it will return its default value. - mutating func clearField6() {self._field6 = nil} - - var field124: Int32 { - get {return _field124 ?? 0} - set {_field124 = newValue} - } - /// Returns true if `field124` has been explicitly set. - var hasField124: Bool {return self._field124 != nil} - /// Clears the value of `field124`. Subsequent reads from it will return its default value. - mutating func clearField124() {self._field124 = nil} - - var field125: Int32 { - get {return _field125 ?? 0} - set {_field125 = newValue} - } - /// Returns true if `field125` has been explicitly set. - var hasField125: Bool {return self._field125 != nil} - /// Clears the value of `field125`. Subsequent reads from it will return its default value. - mutating func clearField125() {self._field125 = nil} - - var field200: Int32 { - get {return _field200 ?? 0} - set {_field200 = newValue} - } - /// Returns true if `field200` has been explicitly set. - var hasField200: Bool {return self._field200 != nil} - /// Clears the value of `field200`. Subsequent reads from it will return its default value. - mutating func clearField200() {self._field200 = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() - fileprivate var _field6: Int32? = nil - fileprivate var _field124: Int32? = nil - fileprivate var _field125: Int32? = nil - fileprivate var _field200: Int32? = nil -} - -/// Intermixed ranges and fields so help ensure no merge issues -struct SDTMsgExtensionRangeOrderingNoMerging: SwiftProtobuf.ExtensibleMessage { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var field1: Int32 { - get {return _field1 ?? 0} - set {_field1 = newValue} - } - /// Returns true if `field1` has been explicitly set. - var hasField1: Bool {return self._field1 != nil} - /// Clears the value of `field1`. Subsequent reads from it will return its default value. - mutating func clearField1() {self._field1 = nil} - - var field2: Int32 { - get {return _field2 ?? 0} - set {_field2 = newValue} - } - /// Returns true if `field2` has been explicitly set. - var hasField2: Bool {return self._field2 != nil} - /// Clears the value of `field2`. Subsequent reads from it will return its default value. - mutating func clearField2() {self._field2 = nil} - - var field6: Int32 { - get {return _field6 ?? 0} - set {_field6 = newValue} - } - /// Returns true if `field6` has been explicitly set. - var hasField6: Bool {return self._field6 != nil} - /// Clears the value of `field6`. Subsequent reads from it will return its default value. - mutating func clearField6() {self._field6 = nil} - - var field13: Int32 { - get {return _field13 ?? 0} - set {_field13 = newValue} - } - /// Returns true if `field13` has been explicitly set. - var hasField13: Bool {return self._field13 != nil} - /// Clears the value of `field13`. Subsequent reads from it will return its default value. - mutating func clearField13() {self._field13 = nil} - - var field15: Int32 { - get {return _field15 ?? 0} - set {_field15 = newValue} - } - /// Returns true if `field15` has been explicitly set. - var hasField15: Bool {return self._field15 != nil} - /// Clears the value of `field15`. Subsequent reads from it will return its default value. - mutating func clearField15() {self._field15 = nil} - - var field21: Int32 { - get {return _field21 ?? 0} - set {_field21 = newValue} - } - /// Returns true if `field21` has been explicitly set. - var hasField21: Bool {return self._field21 != nil} - /// Clears the value of `field21`. Subsequent reads from it will return its default value. - mutating func clearField21() {self._field21 = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - var _protobuf_extensionFieldValues = SwiftProtobuf.ExtensionFieldValueSet() - fileprivate var _field1: Int32? = nil - fileprivate var _field2: Int32? = nil - fileprivate var _field6: Int32? = nil - fileprivate var _field13: Int32? = nil - fileprivate var _field15: Int32? = nil - fileprivate var _field21: Int32? = nil -} - #if swift(>=5.5) && canImport(_Concurrency) extension SDTTopLevelMessage: @unchecked Sendable {} extension SDTTopLevelMessage.OneOf_O: @unchecked Sendable {} @@ -568,9 +428,6 @@ extension SDTExternalRefs: @unchecked Sendable {} extension SDTScoperForExt: @unchecked Sendable {} extension SDTProto2MessageForPresence: @unchecked Sendable {} extension SDTProto2MessageForPresence.OneOf_O: @unchecked Sendable {} -extension SDTMsgExtensionRangeOrdering: @unchecked Sendable {} -extension SDTMsgExtensionRangeOrderingWithFields: @unchecked Sendable {} -extension SDTMsgExtensionRangeOrderingNoMerging: @unchecked Sendable {} #endif // swift(>=5.5) && canImport(_Concurrency) // MARK: - Extension support defined in pluginlib_descriptor_test.proto. @@ -1265,179 +1122,3 @@ extension SDTProto2MessageForPresence: SwiftProtobuf.Message, SwiftProtobuf._Mes return true } } - -extension SDTMsgExtensionRangeOrdering: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".MsgExtensionRangeOrdering" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() - - public var isInitialized: Bool { - if !_protobuf_extensionFieldValues.isInitialized {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1..<5, 7, 9, 100..<121, 126..<131: - try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: SDTMsgExtensionRangeOrdering.self, fieldNumber: fieldNumber) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1, end: 131) - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: SDTMsgExtensionRangeOrdering, rhs: SDTMsgExtensionRangeOrdering) -> Bool { - if lhs.unknownFields != rhs.unknownFields {return false} - if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} - return true - } -} - -extension SDTMsgExtensionRangeOrderingWithFields: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".MsgExtensionRangeOrderingWithFields" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 6: .same(proto: "field6"), - 124: .same(proto: "field124"), - 125: .same(proto: "field125"), - 200: .same(proto: "field200"), - ] - - public var isInitialized: Bool { - if !_protobuf_extensionFieldValues.isInitialized {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 6: try { try decoder.decodeSingularInt32Field(value: &self._field6) }() - case 124: try { try decoder.decodeSingularInt32Field(value: &self._field124) }() - case 125: try { try decoder.decodeSingularInt32Field(value: &self._field125) }() - case 200: try { try decoder.decodeSingularInt32Field(value: &self._field200) }() - case 1..<5, 7, 9, 100..<121, 126..<131: - try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: SDTMsgExtensionRangeOrderingWithFields.self, fieldNumber: fieldNumber) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 1, end: 5) - try { if let v = self._field6 { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 6) - } }() - try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 7, end: 121) - try { if let v = self._field124 { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 124) - } }() - try { if let v = self._field125 { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 125) - } }() - try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 126, end: 131) - try { if let v = self._field200 { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 200) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: SDTMsgExtensionRangeOrderingWithFields, rhs: SDTMsgExtensionRangeOrderingWithFields) -> Bool { - if lhs._field6 != rhs._field6 {return false} - if lhs._field124 != rhs._field124 {return false} - if lhs._field125 != rhs._field125 {return false} - if lhs._field200 != rhs._field200 {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} - return true - } -} - -extension SDTMsgExtensionRangeOrderingNoMerging: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".MsgExtensionRangeOrderingNoMerging" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "field1"), - 2: .same(proto: "field2"), - 6: .same(proto: "field6"), - 13: .same(proto: "field13"), - 15: .same(proto: "field15"), - 21: .same(proto: "field21"), - ] - - public var isInitialized: Bool { - if !_protobuf_extensionFieldValues.isInitialized {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularInt32Field(value: &self._field1) }() - case 2: try { try decoder.decodeSingularInt32Field(value: &self._field2) }() - case 6: try { try decoder.decodeSingularInt32Field(value: &self._field6) }() - case 13: try { try decoder.decodeSingularInt32Field(value: &self._field13) }() - case 15: try { try decoder.decodeSingularInt32Field(value: &self._field15) }() - case 21: try { try decoder.decodeSingularInt32Field(value: &self._field21) }() - case 3..<6, 7..<13, 16..<21: - try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: SDTMsgExtensionRangeOrderingNoMerging.self, fieldNumber: fieldNumber) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._field1 { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) - } }() - try { if let v = self._field2 { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) - } }() - try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 3, end: 6) - try { if let v = self._field6 { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 6) - } }() - try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 7, end: 13) - try { if let v = self._field13 { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 13) - } }() - try { if let v = self._field15 { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 15) - } }() - try visitor.visitExtensionFields(fields: _protobuf_extensionFieldValues, start: 16, end: 21) - try { if let v = self._field21 { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 21) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: SDTMsgExtensionRangeOrderingNoMerging, rhs: SDTMsgExtensionRangeOrderingNoMerging) -> Bool { - if lhs._field1 != rhs._field1 {return false} - if lhs._field2 != rhs._field2 {return false} - if lhs._field6 != rhs._field6 {return false} - if lhs._field13 != rhs._field13 {return false} - if lhs._field15 != rhs._field15 {return false} - if lhs._field21 != rhs._field21 {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - if lhs._protobuf_extensionFieldValues != rhs._protobuf_extensionFieldValues {return false} - return true - } -} diff --git a/Sources/SwiftProtobufPluginLibrary/Descriptor.swift b/Sources/SwiftProtobufPluginLibrary/Descriptor.swift index 9d6fa27d0..cb3adfa16 100644 --- a/Sources/SwiftProtobufPluginLibrary/Descriptor.swift +++ b/Sources/SwiftProtobufPluginLibrary/Descriptor.swift @@ -306,64 +306,6 @@ public final class Descriptor { /// the order they are defined in the .proto file. public let extensionRanges: [Google_Protobuf_DescriptorProto.ExtensionRange] - // TODO(TVL): These next two aren't part of the C++ descriptor api, but since - // they cache for performance, they currently need to be here; should likely - // revisit this and potentilally move them into the plugin in some way. - - /// The `extensionRanges` are in the order they appear in the original .proto - /// file; this orders them and then merges any ranges that are actually - /// contiguious (i.e. - [(21,30),(10,20)] -> [(10,30)]) - /// - /// This also uses Range<> since the options that could be on - /// `extensionRanges` no longer can apply as the things have been merged. - public private(set) lazy var normalizedExtensionRanges: [Range] = { - var ordered: [Range] = self.extensionRanges.sorted(by: { return $0.start < $1.start }).map { return $0.start ..< $0.end } - if ordered.count > 1 { - for i in (0..<(ordered.count - 1)).reversed() { - if ordered[i].upperBound == ordered[i+1].lowerBound { - ordered[i] = ordered[i].lowerBound ..< ordered[i+1].upperBound - ordered.remove(at: i + 1) - } - } - } - return ordered - }() - - /// The `extensionRanges` from `normalizedExtensionRanges`, but takes a step - /// further in that any ranges that do _not_ have any fields inbetween them - /// are also merged together. These can then be used in context where it is - /// ok to include field numbers that have to be extension or unknown fields. - /// - /// This also uses Range<> since the options that could be on - /// `extensionRanges` no longer can apply as the things have been merged. - public private(set) lazy var ambitiousExtensionRanges: [Range] = { - var merged = self.normalizedExtensionRanges - var sortedFields = self.fields.sorted {$0.number < $1.number} - if merged.count > 1 { - var fieldNumbersReversedIterator = - self.fields.map({ Int($0.number) }).sorted(by: { $0 > $1 }).makeIterator() - var nextFieldNumber = fieldNumbersReversedIterator.next() - while nextFieldNumber != nil && merged.last!.lowerBound < nextFieldNumber! { - nextFieldNumber = fieldNumbersReversedIterator.next() - } - - for i in (0..<(merged.count - 1)).reversed() { - if nextFieldNumber == nil || merged[i].lowerBound > nextFieldNumber! { - // No fields left or range starts after the next field, merge it with - // the previous one. - merged[i] = merged[i].lowerBound ..< merged[i+1].upperBound - merged.remove(at: i + 1) - } else { - // can't merge, find the next field number below this range. - while nextFieldNumber != nil && merged[i].lowerBound < nextFieldNumber! { - nextFieldNumber = fieldNumbersReversedIterator.next() - } - } - } - } - return merged - }() - /// The reserved field number ranges for this message. These are returned /// in the order they are defined in the .proto file. public let reservedRanges: [Range] diff --git a/Sources/protoc-gen-swift/Descriptor+Extensions.swift b/Sources/protoc-gen-swift/Descriptor+Extensions.swift index 2732a612a..130b97089 100644 --- a/Sources/protoc-gen-swift/Descriptor+Extensions.swift +++ b/Sources/protoc-gen-swift/Descriptor+Extensions.swift @@ -64,26 +64,59 @@ extension Descriptor { return helper(self) } - /// A `String` containing a comma-delimited list of Swift expressions - /// covering the extension ranges for this message. + /// The `extensionRanges` are in the order they appear in the original .proto + /// file; this orders them and then merges any ranges that are actually + /// contiguious (i.e. - [(21,30),(10,20)] -> [(10,30)]) /// - /// This expression list is suitable as a pattern match in a `case` - /// statement. For example, `"case 5..<10, 15, 20..<30:"`. - var swiftExtensionRangeCaseExpressions: String { - return normalizedExtensionRanges.lazy.map { - $0.swiftCaseExpression - }.joined(separator: ", ") + /// This also uses Range<> since the options that could be on + /// `extensionRanges` no longer can apply as the things have been merged. + var normalizedExtensionRanges: [Range] { + var ordered: [Range] = self.extensionRanges.sorted(by: { + return $0.start < $1.start }).map { return $0.start ..< $0.end + } + if ordered.count > 1 { + for i in (0..<(ordered.count - 1)).reversed() { + if ordered[i].upperBound == ordered[i+1].lowerBound { + ordered[i] = ordered[i].lowerBound ..< ordered[i+1].upperBound + ordered.remove(at: i + 1) + } + } + } + return ordered } - /// A `String` containing a Swift Boolean expression that tests if the given - /// variable is in any of the extension ranges for this message. + /// The `extensionRanges` from `normalizedExtensionRanges`, but takes a step + /// further in that any ranges that do _not_ have any fields inbetween them + /// are also merged together. These can then be used in context where it is + /// ok to include field numbers that have to be extension or unknown fields. /// - /// - Parameter variable: The name of the variable to test in the expression. - /// - Returns: A `String` containing the Boolean expression. - func swiftExtensionRangeBooleanExpression(variable: String) -> String { - return normalizedExtensionRanges.lazy.map { - "(\($0.swiftBooleanExpression(variable: variable)))" - }.joined(separator: " || ") + /// This also uses Range<> since the options that could be on + /// `extensionRanges` no longer can apply as the things have been merged. + var ambitiousExtensionRanges: [Range] { + var merged = self.normalizedExtensionRanges + if merged.count > 1 { + var fieldNumbersReversedIterator = + self.fields.map({ Int($0.number) }).sorted(by: { $0 > $1 }).makeIterator() + var nextFieldNumber = fieldNumbersReversedIterator.next() + while nextFieldNumber != nil && merged.last!.lowerBound < nextFieldNumber! { + nextFieldNumber = fieldNumbersReversedIterator.next() + } + + for i in (0..<(merged.count - 1)).reversed() { + if nextFieldNumber == nil || merged[i].lowerBound > nextFieldNumber! { + // No fields left or range starts after the next field, merge it with + // the previous one. + merged[i] = merged[i].lowerBound ..< merged[i+1].upperBound + merged.remove(at: i + 1) + } else { + // can't merge, find the next field number below this range. + while nextFieldNumber != nil && merged[i].lowerBound < nextFieldNumber! { + nextFieldNumber = fieldNumbersReversedIterator.next() + } + } + } + } + return merged } } diff --git a/Sources/protoc-gen-swift/MessageGenerator.swift b/Sources/protoc-gen-swift/MessageGenerator.swift index 1208c1ad8..8efdd156f 100644 --- a/Sources/protoc-gen-swift/MessageGenerator.swift +++ b/Sources/protoc-gen-swift/MessageGenerator.swift @@ -291,7 +291,8 @@ class MessageGenerator { // code. This also avoids typechecking performance issues if there are // dozens of ranges because we aren't constructing a single large // expression containing untyped integer literals. - if !fields.isEmpty || descriptor.extensionRanges.count > 3 { + let normalizedExtensionRanges = descriptor.normalizedExtensionRanges + if !fields.isEmpty || normalizedExtensionRanges.count > 3 { p.print(""" // The use of inline closures is to circumvent an issue where the compiler // allocates stack space for every case branch when no optimizations are @@ -302,7 +303,7 @@ class MessageGenerator { f.generateDecodeFieldCase(printer: &p) } if isExtensible { - p.print("case \(descriptor.swiftExtensionRangeCaseExpressions):") + p.print("case \(normalizedExtensionRanges.swiftCaseExpression):") p.printIndented("try { try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: \(swiftFullName).self, fieldNumber: fieldNumber) }()") } p.print( @@ -311,7 +312,7 @@ class MessageGenerator { } else if isExtensible { // Just output a simple if-statement if the message had no fields of its // own but we still need to generate a decode statement for extensions. - p.print("if \(descriptor.swiftExtensionRangeBooleanExpression(variable: "fieldNumber")) {") + p.print("if \(normalizedExtensionRanges.swiftBooleanExpression(variable: "fieldNumber")) {") p.printIndented("try decoder.decodeExtensionField(values: &_protobuf_extensionFieldValues, messageType: \(swiftFullName).self, fieldNumber: fieldNumber)") p.print("}") } diff --git a/Sources/protoc-gen-swift/Range+Extensions.swift b/Sources/protoc-gen-swift/Range+Extensions.swift index 929b3a617..712a3fec8 100644 --- a/Sources/protoc-gen-swift/Range+Extensions.swift +++ b/Sources/protoc-gen-swift/Range+Extensions.swift @@ -41,3 +41,29 @@ extension Range where Bound == Int32 { } } + +extension Array where Element == Range { + + /// A `String` containing a comma-delimited list of Swift expressions for + /// the ranges. + /// + /// This expression list is suitable as a pattern match in a `case` + /// statement. For example, `"case 5..<10, 15, 20..<30:"`. + /// + /// - Returns: A `String` containing the comma-delimted expressions. + var swiftCaseExpression: String { + return map { $0.swiftCaseExpression }.joined(separator: ", ") + } + + /// A `String` containing a Swift Boolean expression that tests if the given + /// variable is in any of ranges. + /// + /// - Parameter variable: The name of the variable to test in the expression. + /// - Returns: A `String` containing the Boolean expression. + func swiftBooleanExpression(variable: String) -> String { + return map { + "(\($0.swiftBooleanExpression(variable: variable)))" + }.joined(separator: " || ") + } + +} diff --git a/Tests/SwiftProtobufPluginLibraryTests/DescriptorTestData.swift b/Tests/SwiftProtobufPluginLibraryTests/DescriptorTestData.swift index d9a82b4d9..43e5e76b6 100644 --- a/Tests/SwiftProtobufPluginLibraryTests/DescriptorTestData.swift +++ b/Tests/SwiftProtobufPluginLibraryTests/DescriptorTestData.swift @@ -732,7 +732,7 @@ let fileDescriptorSetBytes: [UInt8] = [ 0x29, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x70, 0x62, 0x0a, 0xc8, 0x17, 0x0a, 0x1f, 0x70, + 0x75, 0x67, 0x69, 0x6e, 0x70, 0x62, 0x0a, 0xc1, 0x13, 0x0a, 0x1f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x6c, 0x69, 0x62, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x73, 0x77, 0x69, 0x66, @@ -915,208 +915,165 @@ let fileDescriptorSetBytes: [UInt8] = [ 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x11, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x03, 0x0a, - 0x01, 0x6f, 0x22, 0x5e, 0x0a, 0x19, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x74, - 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, - 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x2a, 0x04, 0x08, 0x01, 0x10, - 0x02, 0x2a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x2a, 0x04, 0x08, 0x02, 0x10, - 0x03, 0x2a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x2a, 0x04, 0x08, 0x07, 0x10, - 0x08, 0x2a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x2a, 0x04, 0x08, 0x64, 0x10, - 0x6f, 0x2a, 0x05, 0x08, 0x7e, 0x10, 0x83, 0x01, 0x2a, 0x04, 0x08, 0x6f, - 0x10, 0x79, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x79, - 0x10, 0x7e, 0x22, 0xd5, 0x01, 0x0a, 0x23, 0x4d, 0x73, 0x67, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x74, 0x68, - 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x36, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x36, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x31, 0x32, 0x34, 0x18, 0x7c, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x08, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, 0x32, 0x34, 0x12, 0x1a, - 0x0a, 0x08, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, 0x32, 0x35, 0x18, 0x7d, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, - 0x32, 0x35, 0x12, 0x1b, 0x0a, 0x08, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x32, - 0x30, 0x30, 0x18, 0xc8, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x32, 0x30, 0x30, 0x2a, 0x04, 0x08, 0x01, 0x10, - 0x02, 0x2a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x2a, 0x04, 0x08, 0x02, 0x10, - 0x03, 0x2a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x2a, 0x04, 0x08, 0x07, 0x10, - 0x08, 0x2a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x2a, 0x04, 0x08, 0x64, 0x10, - 0x6f, 0x2a, 0x05, 0x08, 0x7e, 0x10, 0x83, 0x01, 0x2a, 0x04, 0x08, 0x6f, - 0x10, 0x79, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x79, - 0x10, 0x7c, 0x22, 0xcc, 0x01, 0x0a, 0x22, 0x4d, 0x73, 0x67, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, - 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4e, 0x6f, 0x4d, 0x65, - 0x72, 0x67, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x31, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x32, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x36, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x36, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x31, 0x33, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, 0x33, 0x12, 0x18, 0x0a, 0x07, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x31, 0x35, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, 0x35, 0x12, 0x18, 0x0a, - 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x32, 0x31, 0x18, 0x15, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x32, 0x31, 0x2a, - 0x04, 0x08, 0x03, 0x10, 0x06, 0x2a, 0x04, 0x08, 0x07, 0x10, 0x0d, 0x2a, - 0x04, 0x08, 0x10, 0x10, 0x15, 0x2a, 0x3c, 0x0a, 0x0c, 0x54, 0x6f, 0x70, - 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0e, 0x0a, - 0x0a, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x10, - 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4f, - 0x4e, 0x45, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x56, 0x41, 0x4c, 0x55, - 0x45, 0x5f, 0x54, 0x57, 0x4f, 0x10, 0x02, 0x32, 0xb1, 0x01, 0x0a, 0x0b, - 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x4a, 0x0a, 0x03, 0x46, 0x6f, 0x6f, 0x12, 0x20, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x63, - 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x56, 0x0a, 0x03, 0x42, 0x61, 0x72, 0x12, 0x26, - 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, - 0x6f, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x1a, 0x27, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, - 0x73, 0x74, 0x2e, 0x54, 0x6f, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x3a, 0x38, 0x0a, 0x07, 0x65, - 0x78, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x90, 0xbf, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, - 0x78, 0x74, 0x53, 0x74, 0x72, 0x42, 0x06, 0xba, 0x02, 0x03, 0x53, 0x44, - 0x54, 0x0a, 0xae, 0x0a, 0x0a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x6c, 0x69, 0x62, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x32, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x15, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, - 0x74, 0x22, 0xc4, 0x09, 0x0a, 0x18, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x50, 0x72, - 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, - 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x73, 0x74, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, - 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x69, 0x6e, - 0x74, 0x33, 0x32, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x56, 0x0a, 0x0a, - 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, - 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, - 0x74, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x50, 0x72, 0x65, - 0x73, 0x65, 0x6e, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x45, 0x6e, 0x75, - 0x6d, 0x52, 0x09, 0x65, 0x6e, 0x75, 0x6d, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x12, 0x48, 0x0a, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x23, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, + 0x01, 0x6f, 0x2a, 0x3c, 0x0a, 0x0c, 0x54, 0x6f, 0x70, 0x4c, 0x65, 0x76, + 0x65, 0x6c, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0e, 0x0a, 0x0a, 0x56, 0x41, + 0x4c, 0x55, 0x45, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x10, 0x00, 0x12, 0x0d, + 0x0a, 0x09, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4f, 0x4e, 0x45, 0x10, + 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x54, + 0x57, 0x4f, 0x10, 0x02, 0x32, 0xb1, 0x01, 0x0a, 0x0b, 0x53, 0x6f, 0x6d, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x03, + 0x46, 0x6f, 0x6f, 0x12, 0x20, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x72, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x56, 0x0a, 0x03, 0x42, 0x61, 0x72, 0x12, 0x26, 0x2e, 0x73, 0x77, + 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x6f, 0x70, 0x4c, + 0x65, 0x76, 0x65, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, + 0x27, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x4f, 0x74, 0x68, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x12, 0x27, 0x0a, 0x0d, 0x6f, 0x70, 0x74, 0x5f, 0x73, 0x74, - 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x01, 0x52, 0x0b, 0x6f, 0x70, 0x74, 0x53, 0x74, 0x72, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x88, 0x01, 0x01, 0x12, 0x2b, 0x0a, 0x0f, 0x6f, - 0x70, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x48, 0x02, 0x52, 0x0d, - 0x6f, 0x70, 0x74, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x88, 0x01, 0x01, 0x12, 0x62, 0x0a, 0x0e, 0x6f, 0x70, 0x74, 0x5f, - 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x0d, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, + 0x54, 0x6f, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x32, 0x3a, 0x38, 0x0a, 0x07, 0x65, 0x78, 0x74, 0x5f, + 0x73, 0x74, 0x72, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x90, + 0xbf, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x78, 0x74, 0x53, + 0x74, 0x72, 0x42, 0x06, 0xba, 0x02, 0x03, 0x53, 0x44, 0x54, 0x0a, 0xae, + 0x0a, 0x0a, 0x20, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x6c, 0x69, 0x62, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, - 0x74, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x50, 0x72, 0x65, - 0x73, 0x65, 0x6e, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x45, 0x6e, 0x75, - 0x6d, 0x48, 0x03, 0x52, 0x0c, 0x6f, 0x70, 0x74, 0x45, 0x6e, 0x75, 0x6d, - 0x46, 0x69, 0x65, 0x6c, 0x64, 0x88, 0x01, 0x01, 0x12, 0x54, 0x0a, 0x11, - 0x6f, 0x70, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x23, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x4f, 0x74, 0x68, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x48, 0x04, 0x52, 0x0f, 0x6f, 0x70, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x88, 0x01, 0x01, 0x12, 0x28, - 0x0a, 0x10, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x5f, 0x73, 0x74, 0x72, - 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x15, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x53, 0x74, 0x72, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x70, 0x65, - 0x61, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x18, 0x16, 0x20, 0x03, 0x28, 0x05, 0x52, 0x10, 0x72, 0x65, - 0x70, 0x65, 0x61, 0x74, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x12, 0x63, 0x0a, 0x11, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, - 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, - 0x17, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x73, 0x77, 0x69, 0x66, - 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x50, 0x72, - 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x45, 0x6e, - 0x75, 0x6d, 0x52, 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x45, 0x6e, - 0x75, 0x6d, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x55, 0x0a, 0x14, 0x72, - 0x65, 0x70, 0x65, 0x61, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x18, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, + 0x74, 0x65, 0x73, 0x74, 0x32, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x15, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x22, 0xc4, + 0x09, 0x0a, 0x18, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x50, 0x72, 0x65, 0x73, 0x65, + 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x5f, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x73, 0x74, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x1f, 0x0a, 0x0b, + 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x33, 0x32, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x56, 0x0a, 0x0a, 0x65, 0x6e, 0x75, + 0x6d, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x37, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, - 0x74, 0x2e, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x52, 0x12, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x28, - 0x0a, 0x0f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x5f, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x00, 0x52, 0x0d, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x53, 0x74, 0x72, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x6f, 0x6e, 0x65, 0x6f, - 0x66, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x18, 0x20, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0f, 0x6f, - 0x6e, 0x65, 0x6f, 0x66, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x12, 0x63, 0x0a, 0x10, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, - 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x21, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, - 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, - 0x74, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x50, 0x72, 0x65, - 0x73, 0x65, 0x6e, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x45, 0x6e, 0x75, - 0x6d, 0x48, 0x00, 0x52, 0x0e, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x45, 0x6e, - 0x75, 0x6d, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x55, 0x0a, 0x13, 0x6f, - 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x23, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, - 0x2e, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x48, 0x00, 0x52, 0x11, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x3c, - 0x0a, 0x07, 0x53, 0x75, 0x62, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0f, 0x0a, - 0x0b, 0x53, 0x55, 0x42, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x30, - 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x55, 0x42, 0x5f, 0x56, 0x41, - 0x4c, 0x55, 0x45, 0x5f, 0x31, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x53, - 0x55, 0x42, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x32, 0x10, 0x02, - 0x42, 0x03, 0x0a, 0x01, 0x6f, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x6f, 0x70, - 0x74, 0x5f, 0x73, 0x74, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x42, - 0x12, 0x0a, 0x10, 0x5f, 0x6f, 0x70, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x33, - 0x32, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x11, 0x0a, 0x0f, 0x5f, - 0x6f, 0x70, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x6f, 0x70, 0x74, 0x5f, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x22, 0x24, 0x0a, 0x0c, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0x92, - 0x02, 0x0a, 0x3f, 0x53, 0x77, 0x69, 0x66, 0x74, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x4c, 0x69, - 0x62, 0x72, 0x61, 0x72, 0x79, 0x2f, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x5f, 0x6d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x73, 0x77, 0x69, 0x66, + 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x09, + 0x65, 0x6e, 0x75, 0x6d, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x48, 0x0a, + 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, + 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x4f, 0x74, 0x68, + 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0c, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, + 0x27, 0x0a, 0x0d, 0x6f, 0x70, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x5f, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, + 0x52, 0x0b, 0x6f, 0x70, 0x74, 0x53, 0x74, 0x72, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x88, 0x01, 0x01, 0x12, 0x2b, 0x0a, 0x0f, 0x6f, 0x70, 0x74, 0x5f, + 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x05, 0x48, 0x02, 0x52, 0x0d, 0x6f, 0x70, 0x74, + 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x88, 0x01, + 0x01, 0x12, 0x62, 0x0a, 0x0e, 0x6f, 0x70, 0x74, 0x5f, 0x65, 0x6e, 0x75, + 0x6d, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x37, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, + 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x45, 0x6e, 0x75, 0x6d, 0x48, 0x03, + 0x52, 0x0c, 0x6f, 0x70, 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x88, 0x01, 0x01, 0x12, 0x54, 0x0a, 0x11, 0x6f, 0x70, 0x74, + 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, + 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x4f, 0x74, 0x68, + 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x04, 0x52, + 0x0f, 0x6f, 0x70, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x10, 0x72, + 0x65, 0x70, 0x65, 0x61, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x5f, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x18, 0x15, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x72, + 0x65, 0x70, 0x65, 0x61, 0x74, 0x53, 0x74, 0x72, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x5f, + 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, + 0x16, 0x20, 0x03, 0x28, 0x05, 0x52, 0x10, 0x72, 0x65, 0x70, 0x65, 0x61, + 0x74, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, + 0x63, 0x0a, 0x11, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x5f, 0x65, 0x6e, + 0x75, 0x6d, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x17, 0x20, 0x03, + 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, + 0x73, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x50, 0x72, 0x65, 0x73, 0x65, + 0x6e, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x45, 0x6e, 0x75, 0x6d, 0x52, + 0x0f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x12, 0x55, 0x0a, 0x14, 0x72, 0x65, 0x70, 0x65, + 0x61, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x18, 0x18, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, + 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x4f, + 0x74, 0x68, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x12, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x6f, + 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x73, 0x74, 0x72, 0x5f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, + 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x53, 0x74, 0x72, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x12, 0x2c, 0x0a, 0x11, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x69, + 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x20, + 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0f, 0x6f, 0x6e, 0x65, 0x6f, + 0x66, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, + 0x63, 0x0a, 0x10, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x65, 0x6e, 0x75, + 0x6d, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x21, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x37, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, + 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x46, 0x6f, 0x72, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x45, 0x6e, 0x75, 0x6d, 0x48, 0x00, + 0x52, 0x0e, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x45, 0x6e, 0x75, 0x6d, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x12, 0x55, 0x0a, 0x13, 0x6f, 0x6e, 0x65, 0x6f, + 0x66, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x4f, 0x74, + 0x68, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, + 0x52, 0x11, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x3c, 0x0a, 0x07, 0x53, + 0x75, 0x62, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x55, + 0x42, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x30, 0x10, 0x00, 0x12, + 0x0f, 0x0a, 0x0b, 0x53, 0x55, 0x42, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, + 0x5f, 0x31, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x55, 0x42, 0x5f, + 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x32, 0x10, 0x02, 0x42, 0x03, 0x0a, + 0x01, 0x6f, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x6f, 0x70, 0x74, 0x5f, 0x73, + 0x74, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x12, 0x0a, 0x10, + 0x5f, 0x6f, 0x70, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6f, 0x70, 0x74, + 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x42, + 0x14, 0x0a, 0x12, 0x5f, 0x6f, 0x70, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x24, 0x0a, + 0x0c, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0x92, 0x02, 0x0a, 0x3f, + 0x53, 0x77, 0x69, 0x66, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x4c, 0x69, 0x62, 0x72, 0x61, + 0x72, 0x79, 0x2f, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x67, 0x65, 0x6e, 0x5f, + 0x73, 0x77, 0x69, 0x66, 0x74, 0x22, 0xac, 0x01, 0x0a, 0x0e, 0x4d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, + 0x12, 0x48, 0x0a, 0x07, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x67, - 0x65, 0x6e, 0x5f, 0x73, 0x77, 0x69, 0x66, 0x74, 0x22, 0xac, 0x01, 0x0a, - 0x0e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x73, 0x12, 0x48, 0x0a, 0x07, 0x6d, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x73, - 0x77, 0x69, 0x66, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x67, 0x65, 0x6e, 0x5f, 0x73, 0x77, 0x69, 0x66, 0x74, 0x2e, - 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x6d, 0x61, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x1a, 0x50, 0x0a, 0x05, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x26, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x66, 0x69, 0x6c, - 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x46, 0x69, 0x6c, 0x65, 0x50, - 0x61, 0x74, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33 + 0x65, 0x6e, 0x5f, 0x73, 0x77, 0x69, 0x66, 0x74, 0x2e, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x2e, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x6d, 0x61, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x1a, 0x50, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33 ] let fileDescriptorSetData = Data(fileDescriptorSetBytes) diff --git a/Tests/SwiftProtobufPluginLibraryTests/Test_Descriptor.swift b/Tests/SwiftProtobufPluginLibraryTests/Test_Descriptor.swift index 374d488b3..c18b593ed 100644 --- a/Tests/SwiftProtobufPluginLibraryTests/Test_Descriptor.swift +++ b/Tests/SwiftProtobufPluginLibraryTests/Test_Descriptor.swift @@ -334,103 +334,4 @@ class Test_Descriptor: XCTestCase { XCTAssertTrue(nestedExt2.file === descriptorTestFile) } - func testExtensionRanges() throws { - let fileSet = try Google_Protobuf_FileDescriptorSet(serializedData: fileDescriptorSetData) - - let descriptorSet = DescriptorSet(proto: fileSet) - - let msgDescriptor = descriptorSet.descriptor(named: "swift_descriptor_test.MsgExtensionRangeOrdering")! - // Quick check of what should be in the proto file - XCTAssertEqual(msgDescriptor.extensionRanges.count, 9) - XCTAssertEqual(msgDescriptor.extensionRanges[0].start, 1) - XCTAssertEqual(msgDescriptor.extensionRanges[1].start, 3) - XCTAssertEqual(msgDescriptor.extensionRanges[2].start, 2) - XCTAssertEqual(msgDescriptor.extensionRanges[3].start, 4) - XCTAssertEqual(msgDescriptor.extensionRanges[4].start, 7) - XCTAssertEqual(msgDescriptor.extensionRanges[5].start, 9) - XCTAssertEqual(msgDescriptor.extensionRanges[6].start, 100) - XCTAssertEqual(msgDescriptor.extensionRanges[7].start, 126) - XCTAssertEqual(msgDescriptor.extensionRanges[8].start, 111) - - // Check sorting/merging - XCTAssertEqual(msgDescriptor.normalizedExtensionRanges.count, 5) - XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[0].lowerBound, 1) - XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[0].upperBound, 5) - XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[1].lowerBound, 7) - XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[1].upperBound, 8) - XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[2].lowerBound, 9) - XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[2].upperBound, 10) - XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[3].lowerBound, 100) - XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[3].upperBound, 121) - XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[4].lowerBound, 126) - XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[4].upperBound, 131) - - - // Check the "ambitious" merging. - XCTAssertEqual(msgDescriptor.ambitiousExtensionRanges.count, 1) - XCTAssertEqual(msgDescriptor.ambitiousExtensionRanges[0].lowerBound, 1) - XCTAssertEqual(msgDescriptor.ambitiousExtensionRanges[0].upperBound, 131) - - let msgDescriptor2 = descriptorSet.descriptor(named: "swift_descriptor_test.MsgExtensionRangeOrderingWithFields")! - // Quick check of what should be in the proto file - XCTAssertEqual(msgDescriptor2.extensionRanges.count, 9) - XCTAssertEqual(msgDescriptor2.extensionRanges[0].start, 1) - XCTAssertEqual(msgDescriptor2.extensionRanges[1].start, 3) - XCTAssertEqual(msgDescriptor2.extensionRanges[2].start, 2) - XCTAssertEqual(msgDescriptor2.extensionRanges[3].start, 4) - XCTAssertEqual(msgDescriptor2.extensionRanges[4].start, 7) - XCTAssertEqual(msgDescriptor2.extensionRanges[5].start, 9) - XCTAssertEqual(msgDescriptor2.extensionRanges[6].start, 100) - XCTAssertEqual(msgDescriptor2.extensionRanges[7].start, 126) - XCTAssertEqual(msgDescriptor2.extensionRanges[8].start, 111) - - // Check sorting/merging - XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges.count, 5) - XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[0].lowerBound, 1) - XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[0].upperBound, 5) - XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[1].lowerBound, 7) - XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[1].upperBound, 8) - XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[2].lowerBound, 9) - XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[2].upperBound, 10) - XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[3].lowerBound, 100) - XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[3].upperBound, 121) - XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[4].lowerBound, 126) - XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[4].upperBound, 131) - - - // Check the "ambitious" merging. - XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges.count, 3) - XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges[0].lowerBound, 1) - XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges[0].upperBound, 5) - XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges[1].lowerBound, 7) - XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges[1].upperBound, 121) - XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges[2].lowerBound, 126) - XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges[2].upperBound, 131) - - let msgDescriptor3 = descriptorSet.descriptor(named: "swift_descriptor_test.MsgExtensionRangeOrderingNoMerging")! - // Quick check of what should be in the proto file - XCTAssertEqual(msgDescriptor3.extensionRanges.count, 3) - XCTAssertEqual(msgDescriptor3.extensionRanges[0].start, 3) - XCTAssertEqual(msgDescriptor3.extensionRanges[1].start, 7) - XCTAssertEqual(msgDescriptor3.extensionRanges[2].start, 16) - - // Check sorting/merging - XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges.count, 3) - XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges[0].lowerBound, 3) - XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges[0].upperBound, 6) - XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges[1].lowerBound, 7) - XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges[1].upperBound, 13) - XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges[2].lowerBound, 16) - XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges[2].upperBound, 21) - - // Check the "ambitious" merging. - XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges.count, 3) - XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges[0].lowerBound, 3) - XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges[0].upperBound, 6) - XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges[1].lowerBound, 7) - XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges[1].upperBound, 13) - XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges[2].lowerBound, 16) - XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges[2].upperBound, 21) - } - } diff --git a/Tests/protoc-gen-swiftTests/DescriptorTestData.swift b/Tests/protoc-gen-swiftTests/DescriptorTestData.swift new file mode 100644 index 000000000..ae2b85479 --- /dev/null +++ b/Tests/protoc-gen-swiftTests/DescriptorTestData.swift @@ -0,0 +1,54 @@ +// See Makefile how this is generated. +// swift-format-ignore-file +import Foundation +let fileDescriptorSetBytes: [UInt8] = [ + 0x0a, 0xbc, 0x04, 0x0a, 0x1c, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x74, + 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x73, + 0x77, 0x69, 0x66, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x22, 0x5e, 0x0a, 0x19, + 0x4d, 0x73, 0x67, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x2a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x2a, 0x04, 0x08, 0x03, 0x10, + 0x04, 0x2a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x2a, 0x04, 0x08, 0x04, 0x10, + 0x05, 0x2a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x2a, 0x04, 0x08, 0x09, 0x10, + 0x0a, 0x2a, 0x04, 0x08, 0x64, 0x10, 0x6f, 0x2a, 0x05, 0x08, 0x7e, 0x10, + 0x83, 0x01, 0x2a, 0x04, 0x08, 0x6f, 0x10, 0x79, 0x4a, 0x04, 0x08, 0x08, + 0x10, 0x09, 0x4a, 0x04, 0x08, 0x79, 0x10, 0x7e, 0x22, 0xd5, 0x01, 0x0a, + 0x23, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x57, 0x69, 0x74, 0x68, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x36, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x36, + 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, 0x32, 0x34, + 0x18, 0x7c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x31, 0x32, 0x34, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x31, 0x32, 0x35, 0x18, 0x7d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, 0x32, 0x35, 0x12, 0x1b, 0x0a, 0x08, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x32, 0x30, 0x30, 0x18, 0xc8, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x08, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x32, 0x30, + 0x30, 0x2a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x2a, 0x04, 0x08, 0x03, 0x10, + 0x04, 0x2a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x2a, 0x04, 0x08, 0x04, 0x10, + 0x05, 0x2a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x2a, 0x04, 0x08, 0x09, 0x10, + 0x0a, 0x2a, 0x04, 0x08, 0x64, 0x10, 0x6f, 0x2a, 0x05, 0x08, 0x7e, 0x10, + 0x83, 0x01, 0x2a, 0x04, 0x08, 0x6f, 0x10, 0x79, 0x4a, 0x04, 0x08, 0x08, + 0x10, 0x09, 0x4a, 0x04, 0x08, 0x79, 0x10, 0x7c, 0x22, 0xcc, 0x01, 0x0a, + 0x22, 0x4d, 0x73, 0x67, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x4e, 0x6f, 0x4d, 0x65, 0x72, 0x67, 0x69, 0x6e, 0x67, 0x12, + 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, 0x12, + 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x32, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x32, 0x12, + 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x36, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x36, 0x12, + 0x18, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, 0x33, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, + 0x33, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x31, 0x35, + 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x31, 0x35, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x32, 0x31, 0x18, 0x15, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x32, 0x31, 0x2a, 0x04, 0x08, 0x03, 0x10, 0x06, 0x2a, + 0x04, 0x08, 0x07, 0x10, 0x0d, 0x2a, 0x04, 0x08, 0x10, 0x10, 0x15 +] +let fileDescriptorSetData = Data(fileDescriptorSetBytes) diff --git a/Tests/protoc-gen-swiftTests/Test_DescriptorExtensions.swift b/Tests/protoc-gen-swiftTests/Test_DescriptorExtensions.swift new file mode 100644 index 000000000..9f0490f67 --- /dev/null +++ b/Tests/protoc-gen-swiftTests/Test_DescriptorExtensions.swift @@ -0,0 +1,117 @@ +// Tests/protoc-gen-swiftTests/Test_DescriptorExtensions.swift - Test Descriptor+Extenions.swift +// +// Copyright (c) 2014 - 2017 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 +// +// ----------------------------------------------------------------------------- + +import XCTest +import SwiftProtobuf +import SwiftProtobufPluginLibrary +@testable import protoc_gen_swift + +class Test_DescriptorExtensions: XCTestCase { + + func testExtensionRanges() throws { + let fileSet = try Google_Protobuf_FileDescriptorSet(serializedData: fileDescriptorSetData) + + let descriptorSet = DescriptorSet(proto: fileSet) + + let msgDescriptor = descriptorSet.descriptor(named: "swift_descriptor_test.MsgExtensionRangeOrdering")! + // Quick check of what should be in the proto file + XCTAssertEqual(msgDescriptor.extensionRanges.count, 9) + XCTAssertEqual(msgDescriptor.extensionRanges[0].start, 1) + XCTAssertEqual(msgDescriptor.extensionRanges[1].start, 3) + XCTAssertEqual(msgDescriptor.extensionRanges[2].start, 2) + XCTAssertEqual(msgDescriptor.extensionRanges[3].start, 4) + XCTAssertEqual(msgDescriptor.extensionRanges[4].start, 7) + XCTAssertEqual(msgDescriptor.extensionRanges[5].start, 9) + XCTAssertEqual(msgDescriptor.extensionRanges[6].start, 100) + XCTAssertEqual(msgDescriptor.extensionRanges[7].start, 126) + XCTAssertEqual(msgDescriptor.extensionRanges[8].start, 111) + + // Check sorting/merging + XCTAssertEqual(msgDescriptor.normalizedExtensionRanges.count, 5) + XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[0].lowerBound, 1) + XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[0].upperBound, 5) + XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[1].lowerBound, 7) + XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[1].upperBound, 8) + XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[2].lowerBound, 9) + XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[2].upperBound, 10) + XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[3].lowerBound, 100) + XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[3].upperBound, 121) + XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[4].lowerBound, 126) + XCTAssertEqual(msgDescriptor.normalizedExtensionRanges[4].upperBound, 131) + + + // Check the "ambitious" merging. + XCTAssertEqual(msgDescriptor.ambitiousExtensionRanges.count, 1) + XCTAssertEqual(msgDescriptor.ambitiousExtensionRanges[0].lowerBound, 1) + XCTAssertEqual(msgDescriptor.ambitiousExtensionRanges[0].upperBound, 131) + + let msgDescriptor2 = descriptorSet.descriptor(named: "swift_descriptor_test.MsgExtensionRangeOrderingWithFields")! + // Quick check of what should be in the proto file + XCTAssertEqual(msgDescriptor2.extensionRanges.count, 9) + XCTAssertEqual(msgDescriptor2.extensionRanges[0].start, 1) + XCTAssertEqual(msgDescriptor2.extensionRanges[1].start, 3) + XCTAssertEqual(msgDescriptor2.extensionRanges[2].start, 2) + XCTAssertEqual(msgDescriptor2.extensionRanges[3].start, 4) + XCTAssertEqual(msgDescriptor2.extensionRanges[4].start, 7) + XCTAssertEqual(msgDescriptor2.extensionRanges[5].start, 9) + XCTAssertEqual(msgDescriptor2.extensionRanges[6].start, 100) + XCTAssertEqual(msgDescriptor2.extensionRanges[7].start, 126) + XCTAssertEqual(msgDescriptor2.extensionRanges[8].start, 111) + + // Check sorting/merging + XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges.count, 5) + XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[0].lowerBound, 1) + XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[0].upperBound, 5) + XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[1].lowerBound, 7) + XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[1].upperBound, 8) + XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[2].lowerBound, 9) + XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[2].upperBound, 10) + XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[3].lowerBound, 100) + XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[3].upperBound, 121) + XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[4].lowerBound, 126) + XCTAssertEqual(msgDescriptor2.normalizedExtensionRanges[4].upperBound, 131) + + + // Check the "ambitious" merging. + XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges.count, 3) + XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges[0].lowerBound, 1) + XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges[0].upperBound, 5) + XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges[1].lowerBound, 7) + XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges[1].upperBound, 121) + XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges[2].lowerBound, 126) + XCTAssertEqual(msgDescriptor2.ambitiousExtensionRanges[2].upperBound, 131) + + let msgDescriptor3 = descriptorSet.descriptor(named: "swift_descriptor_test.MsgExtensionRangeOrderingNoMerging")! + // Quick check of what should be in the proto file + XCTAssertEqual(msgDescriptor3.extensionRanges.count, 3) + XCTAssertEqual(msgDescriptor3.extensionRanges[0].start, 3) + XCTAssertEqual(msgDescriptor3.extensionRanges[1].start, 7) + XCTAssertEqual(msgDescriptor3.extensionRanges[2].start, 16) + + // Check sorting/merging + XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges.count, 3) + XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges[0].lowerBound, 3) + XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges[0].upperBound, 6) + XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges[1].lowerBound, 7) + XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges[1].upperBound, 13) + XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges[2].lowerBound, 16) + XCTAssertEqual(msgDescriptor3.normalizedExtensionRanges[2].upperBound, 21) + + // Check the "ambitious" merging. + XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges.count, 3) + XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges[0].lowerBound, 3) + XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges[0].upperBound, 6) + XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges[1].lowerBound, 7) + XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges[1].upperBound, 13) + XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges[2].lowerBound, 16) + XCTAssertEqual(msgDescriptor3.ambitiousExtensionRanges[2].upperBound, 21) + } + +}