[ObjC] Add Swift helpers for `GPBUnknownFields`/`GPBUnknownField`.

`GPBUnknownFields` additions:
- Provide `Optional` based apis for the `getFirst*` apis.
- Map the `NSFastEnumeration` over as a `Sequence` to support looping over the fields.

`GPBUnknownField` addition:
- Add an `enum` with associated values to provide a more type-safe way for inspection.

PiperOrigin-RevId: 649090744
pull/17297/head
Thomas Van Lenten 9 months ago committed by Copybara-Service
parent 73db255168
commit 6750ed8cd8
  1. 5
      Protobuf.podspec
  2. 42
      objectivec/GPBUnknownField+Additions.swift
  3. 53
      objectivec/GPBUnknownFields+Additions.swift
  4. 20
      objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
  5. 20
      objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
  6. 20
      objectivec/ProtocolBuffers_tvOS.xcodeproj/project.pbxproj
  7. 164
      objectivec/Tests/GPBSwiftTests.swift

@ -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"
}

@ -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)")
}
}
}

@ -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)
}
}

@ -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 = "<group>"; };
F43ADD322C2F2BAD005312E5 /* GPBUnknownFieldsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBUnknownFieldsTest.m; sourceTree = "<group>"; };
F43ADD422C2F381F005312E5 /* GPBCompileTest25.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCompileTest25.m; sourceTree = "<group>"; };
F43ADD4F2C333D6B005312E5 /* GPBUnknownFields+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownFields+Additions.swift"; sourceTree = "<group>"; };
F43ADD552C345CED005312E5 /* GPBUnknownField+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownField+Additions.swift"; sourceTree = "<group>"; };
F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_unittest_data.txt; sourceTree = "<group>"; };
F4411BE71AF12FD700324B4A /* GPBArray_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBArray_PackagePrivate.h; sourceTree = "<group>"; };
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;

@ -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 = "<group>"; };
F43ADD372C2F2D06005312E5 /* GPBUnknownFields.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBUnknownFields.h; sourceTree = "<group>"; };
F43ADD462C2F387A005312E5 /* GPBCompileTest25.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCompileTest25.m; sourceTree = "<group>"; };
F43ADD512C333E58005312E5 /* GPBUnknownFields+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownFields+Additions.swift"; sourceTree = "<group>"; };
F43ADD572C345D0D005312E5 /* GPBUnknownField+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownField+Additions.swift"; sourceTree = "<group>"; };
F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_unittest_data.txt; sourceTree = "<group>"; };
F4411BE81AF1301700324B4A /* GPBArray_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBArray_PackagePrivate.h; sourceTree = "<group>"; };
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 = (

@ -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 = "<group>"; };
F43ADD3C2C2F2D3D005312E5 /* GPBUnknownFields.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBUnknownFields.h; sourceTree = "<group>"; };
F43ADD482C2F389D005312E5 /* GPBCompileTest25.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCompileTest25.m; sourceTree = "<group>"; };
F43ADD532C333EE5005312E5 /* GPBUnknownFields+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownFields+Additions.swift"; sourceTree = "<group>"; };
F43ADD592C345D36005312E5 /* GPBUnknownField+Additions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GPBUnknownField+Additions.swift"; sourceTree = "<group>"; };
F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_unittest_data.txt; sourceTree = "<group>"; };
F4411BE81AF1301700324B4A /* GPBArray_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBArray_PackagePrivate.h; sourceTree = "<group>"; };
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 = (

@ -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)
}
}

Loading…
Cancel
Save