Skip to content

Commit

Permalink
[ObjC] Add Swift helpers for GPBUnknownFields/GPBUnknownField.
Browse files Browse the repository at this point in the history
`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
  • Loading branch information
thomasvl authored and copybara-github committed Jul 3, 2024
1 parent 73db255 commit 6750ed8
Show file tree
Hide file tree
Showing 7 changed files with 298 additions and 26 deletions.
5 changes: 4 additions & 1 deletion Protobuf.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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"
}
Expand Down
42 changes: 42 additions & 0 deletions objectivec/GPBUnknownField+Additions.swift
Original file line number Diff line number Diff line change
@@ -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)")
}
}

}
53 changes: 53 additions & 0 deletions objectivec/GPBUnknownFields+Additions.swift
Original file line number Diff line number Diff line change
@@ -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)
}
}
20 changes: 20 additions & 0 deletions objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -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; };
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -668,6 +674,9 @@
LastTestingUpgradeCheck = 0600;
LastUpgradeCheck = 1400;
TargetAttributes = {
7461B52D0F94FAF800A0C422 = {
LastSwiftMigration = 1530;
};
8BBEA4A5147C727100C4ADB7 = {
LastSwiftMigration = "";
TestTargetID = 8B9A5EA41831993600A9D33B;
Expand Down Expand Up @@ -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 */,
Expand All @@ -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 */,
Expand Down Expand Up @@ -834,28 +845,36 @@
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;
};
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;
};
8BBEA4A7147C727100C4ADB7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
COMBINE_HIDPI_IMAGES = YES;
Expand Down Expand Up @@ -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;
Expand Down
20 changes: 20 additions & 0 deletions objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -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; };
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -673,6 +679,9 @@
LastTestingUpgradeCheck = 0600;
LastUpgradeCheck = 1400;
TargetAttributes = {
7461B52D0F94FAF800A0C422 = {
LastSwiftMigration = 1530;
};
8BBEA4A5147C727100C4ADB7 = {
LastSwiftMigration = 0940;
TestTargetID = 8B9A5EA41831993600A9D33B;
Expand Down Expand Up @@ -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 */,
Expand All @@ -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 */,
Expand Down Expand Up @@ -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)";
};
Expand All @@ -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)";
};
Expand All @@ -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 = (
Expand Down Expand Up @@ -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 = (
Expand Down
Loading

0 comments on commit 6750ed8

Please sign in to comment.