Skip to content

Commit 287f09b

Browse files
authored
Merge pull request #1693 from pouyayarandi/fieldmask-documentation
Documentation for fieldmask utilities
2 parents 3a4c97d + 5a2daa5 commit 287f09b

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

Documentation/API.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,42 @@ public func -(lhs: Google_Protobuf_Timestamp, rhs: Google_Protobuf_Duration) ->
615615
public func +(lhs: Google_Protobuf_Timestamp, rhs: Google_Protobuf_Duration) -> Google_Protobuf_Timestamp
616616
```
617617

618+
### Google_Protobuf_FieldMask
619+
620+
`Google_Protobuf_FieldMask` is used to specify which fields in
621+
a protocol buffer message should be included in operations such as updates or merges.
622+
It allows precise control over which parts of the message
623+
are affected by defining a list of field paths.
624+
625+
For example, consider a protocol buffer message with nested fields:
626+
627+
```protobuf
628+
message ParentMessage {
629+
string name = 1;
630+
ChildMessage child = 2;
631+
632+
message ChildMessage {
633+
string childName = 1;
634+
int32 age = 2;
635+
}
636+
}
637+
```
638+
639+
If you want to update only the `name` field of `ParentMessage`
640+
and the `childName` field within `ChildMessage`,
641+
you would use a `FieldMask` as follows:
642+
643+
```swift
644+
let fieldMask = Google_Protobuf_FieldMask.with {
645+
$0.paths = ["name", "child.childName"]
646+
}
647+
```
648+
649+
In this example, the `paths` list includes `"name"` to target
650+
the `name` field in `ParentMessage` and `"child.childName"`
651+
to target the `childName` field inside the nested `ChildMessage`.
652+
This setup allows you to perform operations that affect
653+
only these specified fields while leaving others unchanged.
618654

619655
## Extensions
620656

@@ -696,6 +732,106 @@ Descriptor objects. It is something that could get revisited in the future,
696732
but will need careful consideration; the bloat/size issues is of the most
697733
concern because of Swift's common use for mobile applications.
698734

735+
## FieldMask Utilities
736+
737+
### Merging Two Messages
738+
739+
The `merge(from:fieldMask:)` function in Swift Protobuf selectively merges
740+
fields from one message into another, guided by a `Google_Protobuf_FieldMask`.
741+
This method is particularly useful when you need to update only specific
742+
fields in a message without affecting others.
743+
The `merge` function is available as a method on `Message` types and requires two parameters:
744+
the source message (`from`) containing the data to merge
745+
and the `fieldMask` that specifies which fields should be updated.
746+
747+
For example, consider a message with the following structure:
748+
749+
```protobuf
750+
message ExampleMessage {
751+
752+
message NestedMessage {
753+
string baz = 1;
754+
string qux = 2;
755+
}
756+
757+
string foo = 1;
758+
string bar = 2;
759+
NestedMessage nested = 3;
760+
}
761+
```
762+
763+
Assume we have two instances of `ExampleMessage`:
764+
765+
```swift
766+
let message1: ExampleMessage = .with {
767+
$0.foo = "foo1"
768+
$0.nested = .with {
769+
$0.baz = "baz1"
770+
}
771+
}
772+
773+
let message2: ExampleMessage = .with {
774+
$0.foo = "foo2"
775+
$0.bar = "bar2"
776+
$0.nested = .with {
777+
$0.baz = "baz2"
778+
$0.qux = "qux2"
779+
}
780+
}
781+
```
782+
783+
To merge `message2` into `message1` but only update the `bar` field
784+
and `qux` field of `nested`, you can use a `Google_Protobuf_FieldMask`
785+
like this:
786+
787+
```swift
788+
let fieldMask = Google_Protobuf_FieldMask.with {
789+
$0.paths = ["bar", "nested.qux"]
790+
}
791+
try message1.merge(from: message2, fieldMask: fieldMask)
792+
```
793+
794+
After this operation, `message1.bar` will have the value `"bar2"` from `message2`,
795+
and `message1.nested.qux` will have the value `"qux2"` from `message2`,
796+
while `message1.foo` and `message1.nested.baz` remain `"foo1"` and `"baz1"`.
797+
Be aware that including `"nested"` in the FieldMask paths will cause all fields
798+
within `message1.nested` to be updated from `message2` (including `baz` and `qux`),
799+
whereas adding `"nested.qux"` only affects the `qux` field in the `nested` message.
800+
The `merge` function operates in-place, meaning it directly modifies `message1`.
801+
802+
### Trimming a Message
803+
804+
The `trim(keeping:)` function retains only specific
805+
fields in a protocol buffer message while clearing the rest.
806+
807+
Consider the `ExampleMessage` structure from the previous example.
808+
Suppose you have an instance of `ExampleMessage` initialized as follows:
809+
810+
```swift
811+
let message = ExampleMessage.with {
812+
$0.foo = "foo"
813+
$0.bar = "bar"
814+
}
815+
```
816+
817+
If you want to trim this message so that only the `bar` field retains its value,
818+
you can use a `Google_Protobuf_FieldMask` like this:
819+
820+
```swift
821+
let fieldMask = Google_Protobuf_FieldMask.with { $0.paths = ["bar"] }
822+
```
823+
824+
Then, you apply the `trim` function:
825+
826+
```swift
827+
message.trim(keeping: fieldMask)
828+
```
829+
830+
After this operation, the `bar` field in `message` will still have the value `"bar"`,
831+
while the `foo` field will be cleared, resetting to its default value (an empty string,
832+
in this case). The `trim(keeping:)` function is performed in-place, meaning it directly
833+
modifies the original message.
834+
699835
## Aside: proto2 vs. proto3
700836

701837
The terms *proto2* and *proto3* refer to two different dialects of the proto

0 commit comments

Comments
 (0)