diff --git a/Protobuf.podspec b/Protobuf.podspec index 00dd468cfe15..3a53918e76bf 100644 --- a/Protobuf.podspec +++ b/Protobuf.podspec @@ -18,7 +18,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/protocolbuffers/protobuf.git', :tag => "v#{s.version}" } - s.source_files = 'objectivec/*.{h,m}', + s.source_files = 'objectivec/*.{h,m,swift}', 'objectivec/google/protobuf/Any.pbobjc.h', 'objectivec/google/protobuf/Api.pbobjc.h', 'objectivec/google/protobuf/Duration.pbobjc.h', @@ -33,6 +33,9 @@ Pod::Spec.new do |s| # left out, as it's an umbrella implementation file. s.exclude_files = 'objectivec/GPBProtocolBuffers.m' + # Now that there is a Swift source file, set a version. + s.swift_version = '5.0' + s.resource_bundle = { "Protobuf_Privacy" => "PrivacyInfo.xcprivacy" } diff --git a/objectivec/GPBUnknownField+Additions.swift b/objectivec/GPBUnknownField+Additions.swift new file mode 100644 index 000000000000..8e2040b2eefb --- /dev/null +++ b/objectivec/GPBUnknownField+Additions.swift @@ -0,0 +1,42 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2024 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +/// Swift specific additions to simplify usage. +extension GPBUnknownField { + + /// The value of the field in a type-safe manner. + public enum Value: Equatable { + case varint(UInt64) + case fixed32(UInt32) + case fixed64(UInt64) + case lengthDelimited(Data) // length prefixed + case group(GPBUnknownFields) // tag delimited + } + + /// The value of the field in a type-safe manner. + /// + /// - Note: This is only valid for non-legacy fields. + public var value: Value { + switch type { + case .varint: + return .varint(varint) + case .fixed32: + return .fixed32(fixed32) + case .fixed64: + return .fixed64(fixed64) + case .lengthDelimited: + return .lengthDelimited(lengthDelimited) + case .group: + return .group(group) + case .legacy: + fatalError("`value` not valid for Legacy fields.") + @unknown default: + fatalError("Internal error: Unknown field type: \(type)") + } + } + +} diff --git a/objectivec/GPBUnknownFields+Additions.swift b/objectivec/GPBUnknownFields+Additions.swift new file mode 100644 index 000000000000..7db0b157c6e3 --- /dev/null +++ b/objectivec/GPBUnknownFields+Additions.swift @@ -0,0 +1,53 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2024 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +/// Swift specific additions to simplify usage. +extension GPBUnknownFields { + + /// Fetches the first varint for the given field number. + public func firstVarint(_ fieldNumber: Int32) -> UInt64? { + var value: UInt64 = 0 + guard getFirst(fieldNumber, varint: &value) else { return nil } + return value + } + + /// Fetches the first fixed32 for the given field number. + public func firstFixed32(_ fieldNumber: Int32) -> UInt32? { + var value: UInt32 = 0 + guard getFirst(fieldNumber, fixed32: &value) else { return nil } + return value + } + + /// Fetches the first fixed64 for the given field number. + public func firstFixed64(_ fieldNumber: Int32) -> UInt64? { + var value: UInt64 = 0 + guard getFirst(fieldNumber, fixed64: &value) else { return nil } + return value + } + +} + +/// Map the `NSFastEnumeration` support to a Swift `Sequence`. +extension GPBUnknownFields: Sequence { + public typealias Element = GPBUnknownField + + public struct Iterator: IteratorProtocol { + var iter: NSFastEnumerationIterator + + init(_ fields: NSFastEnumeration) { + self.iter = NSFastEnumerationIterator(fields) + } + + public mutating func next() -> GPBUnknownField? { + return iter.next() as? GPBUnknownField + } + } + + public func makeIterator() -> Iterator { + return Iterator(self) + } +} diff --git a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj index b40bf9c7543e..32bfb22a3c85 100644 --- a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj +++ b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj @@ -74,6 +74,8 @@ F43ADD312C2F2B91005312E5 /* GPBUnknownFields.h in Headers */ = {isa = PBXBuildFile; fileRef = F43ADD2F2C2F2B91005312E5 /* GPBUnknownFields.h */; }; F43ADD332C2F2BAD005312E5 /* GPBUnknownFieldsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD322C2F2BAD005312E5 /* GPBUnknownFieldsTest.m */; }; F43ADD432C2F381F005312E5 /* GPBCompileTest25.m in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD422C2F381F005312E5 /* GPBCompileTest25.m */; }; + F43ADD502C333D6C005312E5 /* GPBUnknownFields+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD4F2C333D6B005312E5 /* GPBUnknownFields+Additions.swift */; }; + F43ADD562C345CED005312E5 /* GPBUnknownField+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD552C345CED005312E5 /* GPBUnknownField+Additions.swift */; }; F43C88D0191D77FC009E917D /* text_format_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */; }; F4487C4D1A9F8E0200531423 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; F4487C521A9F8E4D00531423 /* GPBProtocolBuffers.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BCF338814ED799900BC5317 /* GPBProtocolBuffers.m */; }; @@ -214,6 +216,8 @@ F43ADD2F2C2F2B91005312E5 /* GPBUnknownFields.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBUnknownFields.h; sourceTree = ""; }; F43ADD322C2F2BAD005312E5 /* GPBUnknownFieldsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBUnknownFieldsTest.m; sourceTree = ""; }; F43ADD422C2F381F005312E5 /* GPBCompileTest25.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCompileTest25.m; sourceTree = ""; }; + F43ADD4F2C333D6B005312E5 /* GPBUnknownFields+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownFields+Additions.swift"; sourceTree = ""; }; + F43ADD552C345CED005312E5 /* GPBUnknownField+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownField+Additions.swift"; sourceTree = ""; }; F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_unittest_data.txt; sourceTree = ""; }; F4411BE71AF12FD700324B4A /* GPBArray_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBArray_PackagePrivate.h; sourceTree = ""; }; F4487C511A9F8E0200531423 /* libTestSingleSourceBuild.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTestSingleSourceBuild.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -417,8 +421,10 @@ F4B6B8AF1A9CC98000892426 /* GPBUnknownField_PackagePrivate.h */, 7461B4AE0F94F99000A0C422 /* GPBUnknownField.h */, 7461B4AF0F94F99000A0C422 /* GPBUnknownField.m */, + F43ADD552C345CED005312E5 /* GPBUnknownField+Additions.swift */, F43ADD2F2C2F2B91005312E5 /* GPBUnknownFields.h */, F43ADD2E2C2F2B91005312E5 /* GPBUnknownFields.m */, + F43ADD4F2C333D6B005312E5 /* GPBUnknownFields+Additions.swift */, F4B6B8B21A9CCBDA00892426 /* GPBUnknownFieldSet_PackagePrivate.h */, 7461B4E10F94F99000A0C422 /* GPBUnknownFieldSet.h */, 7461B4E20F94F99000A0C422 /* GPBUnknownFieldSet.m */, @@ -668,6 +674,9 @@ LastTestingUpgradeCheck = 0600; LastUpgradeCheck = 1400; TargetAttributes = { + 7461B52D0F94FAF800A0C422 = { + LastSwiftMigration = 1530; + }; 8BBEA4A5147C727100C4ADB7 = { LastSwiftMigration = ""; TestTargetID = 8B9A5EA41831993600A9D33B; @@ -719,6 +728,7 @@ files = ( F47CF93123D9006000C7B24C /* GPBType.pbobjc.m in Sources */, 7461B53C0F94FB4E00A0C422 /* GPBCodedInputStream.m in Sources */, + F43ADD502C333D6C005312E5 /* GPBUnknownFields+Additions.swift in Sources */, F47CF93223D9006000C7B24C /* GPBWrappers.pbobjc.m in Sources */, F47CF94123D902D500C7B24C /* GPBEmpty.pbobjc.m in Sources */, F43ADD302C2F2B91005312E5 /* GPBUnknownFields.m in Sources */, @@ -737,6 +747,7 @@ 8B79657B14992E3F002FFBFC /* GPBRootObject.m in Sources */, F47CF93523D9006000C7B24C /* GPBTimestamp.pbobjc.m in Sources */, 8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */, + F43ADD562C345CED005312E5 /* GPBUnknownField+Additions.swift in Sources */, F45C69CC16DFD08D0081955B /* GPBExtensionInternals.m in Sources */, F47CF92B23D9006000C7B24C /* GPBStruct.pbobjc.m in Sources */, F47CF94323D902D500C7B24C /* GPBAny.pbobjc.m in Sources */, @@ -834,10 +845,14 @@ 7461B52F0F94FAFA00A0C422 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; COMBINE_HIDPI_IMAGES = YES; DEAD_CODE_STRIPPING = YES; PRODUCT_NAME = ProtocolBuffers; + SWIFT_OBJC_BRIDGING_HEADER = GPBProtocolBuffers.h; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)"; }; name = Debug; @@ -845,10 +860,13 @@ 7461B5300F94FAFA00A0C422 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; COMBINE_HIDPI_IMAGES = YES; DEAD_CODE_STRIPPING = YES; PRODUCT_NAME = ProtocolBuffers; + SWIFT_OBJC_BRIDGING_HEADER = GPBProtocolBuffers.h; + SWIFT_VERSION = 5.0; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)"; }; name = Release; @@ -856,6 +874,7 @@ 8BBEA4A7147C727100C4ADB7 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; COMBINE_HIDPI_IMAGES = YES; @@ -888,6 +907,7 @@ 8BBEA4A8147C727100C4ADB7 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; COMBINE_HIDPI_IMAGES = YES; diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj index 2438b6a3bb1c..a01147a03b01 100644 --- a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj +++ b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj @@ -73,6 +73,8 @@ F43ADD352C2F2CE9005312E5 /* GPBUnknownFieldsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD342C2F2CE9005312E5 /* GPBUnknownFieldsTest.m */; }; F43ADD412C2F2D60005312E5 /* GPBUnknownFields.m in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD362C2F2D06005312E5 /* GPBUnknownFields.m */; }; F43ADD472C2F387A005312E5 /* GPBCompileTest25.m in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD462C2F387A005312E5 /* GPBCompileTest25.m */; }; + F43ADD522C333E58005312E5 /* GPBUnknownFields+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD512C333E58005312E5 /* GPBUnknownFields+Additions.swift */; }; + F43ADD582C345D0D005312E5 /* GPBUnknownField+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD572C345D0D005312E5 /* GPBUnknownField+Additions.swift */; }; F43C88D0191D77FC009E917D /* text_format_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */; }; F4487C6A1A9F8F8100531423 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; F4487C6F1A9F8FFF00531423 /* GPBProtocolBuffers.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BCF338814ED799900BC5317 /* GPBProtocolBuffers.m */; }; @@ -214,6 +216,8 @@ F43ADD362C2F2D06005312E5 /* GPBUnknownFields.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBUnknownFields.m; sourceTree = ""; }; F43ADD372C2F2D06005312E5 /* GPBUnknownFields.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBUnknownFields.h; sourceTree = ""; }; F43ADD462C2F387A005312E5 /* GPBCompileTest25.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCompileTest25.m; sourceTree = ""; }; + F43ADD512C333E58005312E5 /* GPBUnknownFields+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownFields+Additions.swift"; sourceTree = ""; }; + F43ADD572C345D0D005312E5 /* GPBUnknownField+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownField+Additions.swift"; sourceTree = ""; }; F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_unittest_data.txt; sourceTree = ""; }; F4411BE81AF1301700324B4A /* GPBArray_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBArray_PackagePrivate.h; sourceTree = ""; }; F4487C6E1A9F8F8100531423 /* libTestSingleSourceBuild.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTestSingleSourceBuild.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -422,8 +426,10 @@ F4B6B8B01A9CC99500892426 /* GPBUnknownField_PackagePrivate.h */, 7461B4AE0F94F99000A0C422 /* GPBUnknownField.h */, 7461B4AF0F94F99000A0C422 /* GPBUnknownField.m */, + F43ADD572C345D0D005312E5 /* GPBUnknownField+Additions.swift */, F43ADD372C2F2D06005312E5 /* GPBUnknownFields.h */, F43ADD362C2F2D06005312E5 /* GPBUnknownFields.m */, + F43ADD512C333E58005312E5 /* GPBUnknownFields+Additions.swift */, F4B6B8B11A9CCBBB00892426 /* GPBUnknownFieldSet_PackagePrivate.h */, 7461B4E10F94F99000A0C422 /* GPBUnknownFieldSet.h */, 7461B4E20F94F99000A0C422 /* GPBUnknownFieldSet.m */, @@ -673,6 +679,9 @@ LastTestingUpgradeCheck = 0600; LastUpgradeCheck = 1400; TargetAttributes = { + 7461B52D0F94FAF800A0C422 = { + LastSwiftMigration = 1530; + }; 8BBEA4A5147C727100C4ADB7 = { LastSwiftMigration = 0940; TestTargetID = 8B9A5EA41831993600A9D33B; @@ -724,6 +733,7 @@ files = ( 7461B53C0F94FB4E00A0C422 /* GPBCodedInputStream.m in Sources */, F47CF96D23D903C600C7B24C /* GPBAny.pbobjc.m in Sources */, + F43ADD522C333E58005312E5 /* GPBUnknownFields+Additions.swift in Sources */, F47CF96623D903C600C7B24C /* GPBSourceContext.pbobjc.m in Sources */, F47CF96C23D903C600C7B24C /* GPBType.pbobjc.m in Sources */, F43ADD412C2F2D60005312E5 /* GPBUnknownFields.m in Sources */, @@ -742,6 +752,7 @@ F47CF96523D903C600C7B24C /* GPBApi.pbobjc.m in Sources */, F4353D271ABB156F005A6198 /* GPBDictionary.m in Sources */, 8B79657B14992E3F002FFBFC /* GPBRootObject.m in Sources */, + F43ADD582C345D0D005312E5 /* GPBUnknownField+Additions.swift in Sources */, F47CF96223D903C600C7B24C /* GPBFieldMask.pbobjc.m in Sources */, 8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */, F45C69CC16DFD08D0081955B /* GPBExtensionInternals.m in Sources */, @@ -839,9 +850,13 @@ 7461B52F0F94FAFA00A0C422 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; PRODUCT_NAME = ProtocolBuffers; SKIP_INSTALL = YES; + SWIFT_OBJC_BRIDGING_HEADER = GPBProtocolBuffers.h; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)"; }; @@ -850,9 +865,12 @@ 7461B5300F94FAFA00A0C422 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; PRODUCT_NAME = ProtocolBuffers; SKIP_INSTALL = YES; + SWIFT_OBJC_BRIDGING_HEADER = GPBProtocolBuffers.h; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)"; }; @@ -861,6 +879,7 @@ 8BBEA4A7147C727100C4ADB7 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -899,6 +918,7 @@ 8BBEA4A8147C727100C4ADB7 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; FRAMEWORK_SEARCH_PATHS = ( diff --git a/objectivec/ProtocolBuffers_tvOS.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_tvOS.xcodeproj/project.pbxproj index d9d698d40b25..76c44664d205 100644 --- a/objectivec/ProtocolBuffers_tvOS.xcodeproj/project.pbxproj +++ b/objectivec/ProtocolBuffers_tvOS.xcodeproj/project.pbxproj @@ -74,6 +74,8 @@ F43ADD3D2C2F2D3D005312E5 /* GPBUnknownFields.m in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD3B2C2F2D3D005312E5 /* GPBUnknownFields.m */; }; F43ADD3E2C2F2D3D005312E5 /* GPBUnknownFields.h in Headers */ = {isa = PBXBuildFile; fileRef = F43ADD3C2C2F2D3D005312E5 /* GPBUnknownFields.h */; }; F43ADD492C2F389D005312E5 /* GPBCompileTest25.m in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD482C2F389D005312E5 /* GPBCompileTest25.m */; }; + F43ADD542C333EE5005312E5 /* GPBUnknownFields+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD532C333EE5005312E5 /* GPBUnknownFields+Additions.swift */; }; + F43ADD5A2C345D36005312E5 /* GPBUnknownField+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43ADD592C345D36005312E5 /* GPBUnknownField+Additions.swift */; }; F43C88D0191D77FC009E917D /* text_format_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */; }; F4487C6A1A9F8F8100531423 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; F4487C6F1A9F8FFF00531423 /* GPBProtocolBuffers.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BCF338814ED799900BC5317 /* GPBProtocolBuffers.m */; }; @@ -215,6 +217,8 @@ F43ADD3B2C2F2D3D005312E5 /* GPBUnknownFields.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBUnknownFields.m; sourceTree = ""; }; F43ADD3C2C2F2D3D005312E5 /* GPBUnknownFields.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBUnknownFields.h; sourceTree = ""; }; F43ADD482C2F389D005312E5 /* GPBCompileTest25.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCompileTest25.m; sourceTree = ""; }; + F43ADD532C333EE5005312E5 /* GPBUnknownFields+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownFields+Additions.swift"; sourceTree = ""; }; + F43ADD592C345D36005312E5 /* GPBUnknownField+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownField+Additions.swift"; sourceTree = ""; }; F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_unittest_data.txt; sourceTree = ""; }; F4411BE81AF1301700324B4A /* GPBArray_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBArray_PackagePrivate.h; sourceTree = ""; }; F4487C6E1A9F8F8100531423 /* libTestSingleSourceBuild.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTestSingleSourceBuild.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -423,8 +427,10 @@ F4B6B8B01A9CC99500892426 /* GPBUnknownField_PackagePrivate.h */, 7461B4AE0F94F99000A0C422 /* GPBUnknownField.h */, 7461B4AF0F94F99000A0C422 /* GPBUnknownField.m */, + F43ADD592C345D36005312E5 /* GPBUnknownField+Additions.swift */, F43ADD3C2C2F2D3D005312E5 /* GPBUnknownFields.h */, F43ADD3B2C2F2D3D005312E5 /* GPBUnknownFields.m */, + F43ADD532C333EE5005312E5 /* GPBUnknownFields+Additions.swift */, F4B6B8B11A9CCBBB00892426 /* GPBUnknownFieldSet_PackagePrivate.h */, 7461B4E10F94F99000A0C422 /* GPBUnknownFieldSet.h */, 7461B4E20F94F99000A0C422 /* GPBUnknownFieldSet.m */, @@ -675,6 +681,9 @@ LastTestingUpgradeCheck = 0600; LastUpgradeCheck = 1400; TargetAttributes = { + 7461B52D0F94FAF800A0C422 = { + LastSwiftMigration = 1530; + }; 8BBEA4A5147C727100C4ADB7 = { LastSwiftMigration = 0940; TestTargetID = 8B9A5EA41831993600A9D33B; @@ -726,6 +735,7 @@ files = ( 7461B53C0F94FB4E00A0C422 /* GPBCodedInputStream.m in Sources */, F4487C731A9F906200531423 /* GPBArray.m in Sources */, + F43ADD542C333EE5005312E5 /* GPBUnknownFields+Additions.swift in Sources */, F47CF98923D904E600C7B24C /* GPBStruct.pbobjc.m in Sources */, F47CF98623D904E600C7B24C /* GPBEmpty.pbobjc.m in Sources */, F43ADD3D2C2F2D3D005312E5 /* GPBUnknownFields.m in Sources */, @@ -744,6 +754,7 @@ F4353D271ABB156F005A6198 /* GPBDictionary.m in Sources */, F47CF98B23D904E600C7B24C /* GPBDuration.pbobjc.m in Sources */, 8B79657B14992E3F002FFBFC /* GPBRootObject.m in Sources */, + F43ADD5A2C345D36005312E5 /* GPBUnknownField+Additions.swift in Sources */, 8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */, F47CF98A23D904E600C7B24C /* GPBFieldMask.pbobjc.m in Sources */, F47CF99423D904E600C7B24C /* GPBAny.pbobjc.m in Sources */, @@ -841,8 +852,12 @@ 7461B52F0F94FAFA00A0C422 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; PRODUCT_NAME = ProtocolBuffers; + SWIFT_OBJC_BRIDGING_HEADER = GPBProtocolBuffers.h; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)"; }; name = Debug; @@ -850,8 +865,11 @@ 7461B5300F94FAFA00A0C422 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; PRODUCT_NAME = ProtocolBuffers; + SWIFT_OBJC_BRIDGING_HEADER = GPBProtocolBuffers.h; + SWIFT_VERSION = 5.0; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)"; }; name = Release; @@ -859,6 +877,7 @@ 8BBEA4A7147C727100C4ADB7 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -896,6 +915,7 @@ 8BBEA4A8147C727100C4ADB7 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; FRAMEWORK_SEARCH_PATHS = ( diff --git a/objectivec/Tests/GPBSwiftTests.swift b/objectivec/Tests/GPBSwiftTests.swift index 8d812c88b7f8..74854865d4bf 100644 --- a/objectivec/Tests/GPBSwiftTests.swift +++ b/objectivec/Tests/GPBSwiftTests.swift @@ -7,9 +7,13 @@ import Foundation import XCTest - +import ProtocolBuffers // Test some usage of the ObjC library from Swift. +private func dataFromStr(_ str: String) -> Data { + return str.data(using: .utf8)! +} + class GPBBridgeTests: XCTestCase { func testProto2Basics() { @@ -30,12 +34,12 @@ class GPBBridgeTests: XCTestCase { msg.repeatedStringArray.add("pqr") msg.repeatedEnumArray.addValue(Message2_Enum.bar.rawValue) msg.repeatedEnumArray.addValue(Message2_Enum.baz.rawValue) - msg.mapInt32Int32.setInt32(400, forKey:500) - msg.mapInt32Int32.setInt32(401, forKey:501) - msg.mapStringString.setObject("foo", forKey:"bar" as NSString) - msg.mapStringString.setObject("abc", forKey:"xyz" as NSString) - msg.mapInt32Enum.setEnum(Message2_Enum.bar.rawValue, forKey:600) - msg.mapInt32Enum.setEnum(Message2_Enum.baz.rawValue, forKey:601) + msg.mapInt32Int32.setInt32(400, forKey: 500) + msg.mapInt32Int32.setInt32(401, forKey: 501) + msg.mapStringString.setObject("foo", forKey: "bar" as NSString) + msg.mapStringString.setObject("abc", forKey: "xyz" as NSString) + msg.mapInt32Enum.setEnum(Message2_Enum.bar.rawValue, forKey: 600) + msg.mapInt32Enum.setEnum(Message2_Enum.baz.rawValue, forKey: 601) // Check has*. XCTAssertTrue(msg.hasOptionalInt32) @@ -76,9 +80,9 @@ class GPBBridgeTests: XCTestCase { XCTAssertEqual(msg.mapStringString.object(forKey: "bar") as? String, "foo") XCTAssertEqual(msg.mapStringString.object(forKey: "xyz") as? String, "abc") XCTAssertEqual(msg.mapInt32Enum.count, UInt(2)) - XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:600)) + XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey: 600)) XCTAssertEqual(intValue, Message2_Enum.bar.rawValue) - XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:601)) + XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey: 601)) XCTAssertEqual(intValue, Message2_Enum.baz.rawValue) // Clearing a string with nil. @@ -128,13 +132,13 @@ class GPBBridgeTests: XCTestCase { msg.repeatedEnumArray.addValue(Message3_Enum.bar.rawValue) msg.repeatedEnumArray.addRawValue(666) SetMessage3_OptionalEnum_RawValue(msg2, 666) - msg.mapInt32Int32.setInt32(400, forKey:500) - msg.mapInt32Int32.setInt32(401, forKey:501) - msg.mapStringString.setObject("foo", forKey:"bar" as NSString) - msg.mapStringString.setObject("abc", forKey:"xyz" as NSString) - msg.mapInt32Enum.setEnum(Message2_Enum.bar.rawValue, forKey:600) + msg.mapInt32Int32.setInt32(400, forKey: 500) + msg.mapInt32Int32.setInt32(401, forKey: 501) + msg.mapStringString.setObject("foo", forKey: "bar" as NSString) + msg.mapStringString.setObject("abc", forKey: "xyz" as NSString) + msg.mapInt32Enum.setEnum(Message2_Enum.bar.rawValue, forKey: 600) // "proto3" syntax lets enum get unknown values. - msg.mapInt32Enum.setRawValue(666, forKey:601) + msg.mapInt32Enum.setRawValue(666, forKey: 601) // Has only exists on for message fields. XCTAssertTrue(msg.hasOptionalMessage) @@ -155,25 +159,26 @@ class GPBBridgeTests: XCTestCase { XCTAssertEqual(msg.repeatedInt64Array.count, UInt(0)) XCTAssertEqual(msg.repeatedEnumArray.count, UInt(2)) XCTAssertEqual(msg.repeatedEnumArray.value(at: 0), Message3_Enum.bar.rawValue) - XCTAssertEqual(msg.repeatedEnumArray.value(at: 1), Message3_Enum.gpbUnrecognizedEnumeratorValue.rawValue) + XCTAssertEqual( + msg.repeatedEnumArray.value(at: 1), Message3_Enum.gpbUnrecognizedEnumeratorValue.rawValue) XCTAssertEqual(msg.repeatedEnumArray.rawValue(at: 1), 666) XCTAssertEqual(msg2.optionalEnum, Message3_Enum.gpbUnrecognizedEnumeratorValue) XCTAssertEqual(Message3_OptionalEnum_RawValue(msg2), Int32(666)) XCTAssertEqual(msg.mapInt32Int32.count, UInt(2)) var intValue: Int32 = 0 - XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey:500)) + XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey: 500)) XCTAssertEqual(intValue, Int32(400)) - XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey:501)) + XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey: 501)) XCTAssertEqual(intValue, Int32(401)) XCTAssertEqual(msg.mapStringString.count, Int(2)) XCTAssertEqual(msg.mapStringString.object(forKey: "bar") as? String, "foo") XCTAssertEqual(msg.mapStringString.object(forKey: "xyz") as? String, "abc") XCTAssertEqual(msg.mapInt32Enum.count, UInt(2)) - XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:600)) + XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey: 600)) XCTAssertEqual(intValue, Message2_Enum.bar.rawValue) - XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:601)) + XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey: 601)) XCTAssertEqual(intValue, Message3_Enum.gpbUnrecognizedEnumeratorValue.rawValue) - XCTAssertTrue(msg.mapInt32Enum.getRawValue(&intValue, forKey:601)) + XCTAssertTrue(msg.mapInt32Enum.getRawValue(&intValue, forKey: 601)) XCTAssertEqual(intValue, 666) // Clearing a string with nil. @@ -416,10 +421,10 @@ class GPBBridgeTests: XCTestCase { msg.optionalGroup.a = 102 msg.repeatedStringArray.add("abc") msg.repeatedStringArray.add("def") - msg.mapInt32Int32.setInt32(200, forKey:300) - msg.mapInt32Int32.setInt32(201, forKey:201) - msg.mapStringString.setObject("foo", forKey:"bar" as NSString) - msg.mapStringString.setObject("abc", forKey:"xyz" as NSString) + msg.mapInt32Int32.setInt32(200, forKey: 300) + msg.mapInt32Int32.setInt32(201, forKey: 201) + msg.mapStringString.setObject("foo", forKey: "bar" as NSString) + msg.mapStringString.setObject("abc", forKey: "xyz" as NSString) let data = msg.data() @@ -434,4 +439,113 @@ class GPBBridgeTests: XCTestCase { XCTAssertEqual(msg2, msg) } + func testUnknownFieldsAdditions_getToOptional() { + let ufs = GPBUnknownFields() + ufs.addFieldNumber(1, varint: 1) + ufs.addFieldNumber(1, varint: 2) + ufs.addFieldNumber(1, fixed32: 3) + ufs.addFieldNumber(1, fixed32: 4) + ufs.addFieldNumber(1, fixed64: 5) + ufs.addFieldNumber(1, fixed64: 6) + ufs.addFieldNumber(1, lengthDelimited: dataFromStr("foo")) + ufs.addFieldNumber(1, lengthDelimited: dataFromStr("bar")) + let group1 = ufs.addGroup(withFieldNumber: 1) + let group2 = ufs.addGroup(withFieldNumber: 1) + XCTAssertFalse(group1 === group2) // Different objects + XCTAssertEqual(ufs.count, 10) + + ufs.addFieldNumber(11, varint: 11) + ufs.addFieldNumber(12, fixed32: 12) + ufs.addFieldNumber(13, fixed64: 13) + ufs.addFieldNumber(14, lengthDelimited: dataFromStr("foo2")) + let group3 = ufs.addGroup(withFieldNumber: 15) + XCTAssertNotNil(group3) + XCTAssertFalse(group3 === group1) // Different objects + XCTAssertFalse(group3 === group2) // Different objects + XCTAssertEqual(ufs.count, 15) + + XCTAssertEqual(ufs.firstVarint(1), 1) + XCTAssertEqual(ufs.firstVarint(11), 11) + XCTAssertNil(ufs.firstVarint(12)) // Different type + XCTAssertNil(ufs.firstVarint(99)) // Not present + + XCTAssertEqual(ufs.firstFixed32(1), 3) + XCTAssertEqual(ufs.firstFixed32(12), 12) + XCTAssertNil(ufs.firstFixed32(11)) // Different type + XCTAssertNil(ufs.firstFixed32(99)) // Not present + + XCTAssertEqual(ufs.firstFixed64(1), 5) + XCTAssertEqual(ufs.firstFixed64(13), 13) + XCTAssertNil(ufs.firstFixed64(11)) // Different type + XCTAssertNil(ufs.firstFixed64(99)) // Not present + + XCTAssertEqual(dataFromStr("foo"), ufs.firstLengthDelimited(1)) + XCTAssertEqual(dataFromStr("foo2"), ufs.firstLengthDelimited(14)) + XCTAssertNil(ufs.firstLengthDelimited(11)) // Different type + XCTAssertNil(ufs.firstLengthDelimited(99)) // Not present + + XCTAssertTrue(group1 === ufs.firstGroup(1)) // Testing ptr, exact object + XCTAssertTrue(group3 === ufs.firstGroup(15)) // Testing ptr, exact object + XCTAssertNil(ufs.firstGroup(11)) // Different type + XCTAssertNil(ufs.firstGroup(99)) // Not present + } + + // This also test the `NSFastEnumeration` -> `Sequence` support. + func testUnknownFieldAdditions_value() { + let ufs = GPBUnknownFields() + ufs.addFieldNumber(1, varint: 1) + ufs.addFieldNumber(2, varint: 2) + ufs.addFieldNumber(1, fixed32: 3) + ufs.addFieldNumber(2, fixed32: 4) + ufs.addFieldNumber(1, fixed64: 5) + ufs.addFieldNumber(3, fixed64: 6) + ufs.addFieldNumber(1, lengthDelimited: dataFromStr("foo")) + ufs.addFieldNumber(2, lengthDelimited: dataFromStr("bar")) + let group1 = ufs.addGroup(withFieldNumber: 1) + group1.addFieldNumber(10, varint: 1) + let group2 = ufs.addGroup(withFieldNumber: 3) + group2.addFieldNumber(10, varint: 2) + + // The order added nothing to do with field numbers. + var loop = 0 + for field in ufs { + loop += 1 + switch loop { + case 1: + XCTAssertEqual(field.number, 1) + XCTAssertEqual(field.value, GPBUnknownField.Value.varint(1)) + case 2: + XCTAssertEqual(field.number, 2) + XCTAssertEqual(field.value, .varint(2)) + case 3: + XCTAssertEqual(field.number, 1) + XCTAssertEqual(field.value, .fixed32(3)) + case 4: + XCTAssertEqual(field.number, 2) + XCTAssertEqual(field.value, .fixed32(4)) + case 5: + XCTAssertEqual(field.number, 1) + XCTAssertEqual(field.value, .fixed64(5)) + case 6: + XCTAssertEqual(field.number, 3) + XCTAssertEqual(field.value, .fixed64(6)) + case 7: + XCTAssertEqual(field.number, 1) + XCTAssertEqual(field.value, .lengthDelimited(dataFromStr("foo"))) + case 8: + XCTAssertEqual(field.number, 2) + XCTAssertEqual(field.value, .lengthDelimited(dataFromStr("bar"))) + case 9: + XCTAssertEqual(field.number, 1) + XCTAssertEqual(field.value, .group(group1)) + case 10: + XCTAssertEqual(field.number, 3) + XCTAssertEqual(field.value, .group(group2)) + default: + XCTFail("Unexpected") + } + } + XCTAssertEqual(loop, 10) + } + }