In the Google Ads API, updates are done using a field mask. The field mask lists
all the fields you intend to change with the update, and any specified fields
that aren't in the field mask are ignored, even if sent to the server. You
can create a field mask manually by creating a [`FieldMask`](https://github.com/protocolbuffers/protobuf/blob/master/php/src/Google/Protobuf/FieldMask.php)
(`Google\Protobuf\FieldMask`), making an array populated with the names of all
the fields you intend to change, and then assigning that array to the field
mask's `paths` field.

You can also use our built-in field mask utility
([`FieldMasks`](https://github.com/googleads/google-ads-php/blob/HEAD/src/Google/Ads/GoogleAds/Util/FieldMasks.php)), which hides many of the specific details and
lets you generate field masks automatically by inspecting the changes you make
to the entity's fields.

Here's an example for updating a campaign:

    $campaign = new Campaign([
        'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
        'status' => CampaignStatusEnum\CampaignStatus::PAUSED
    ]);

    $campaignOperation = new CampaignOperation();
    $campaignOperation->setUpdate($campaign);
    $campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));

This code first creates a `Campaign` object and then sets its resource name
using [`ResourceNames`](https://developers.google.com/google-ads/api/docs/client-libs/php/resourcenames), so that the API knows which campaign is
being updated. `status` is also set to `CampaignStatus::PAUSED`.

The code then creates a `CampaignOperation` object and sets the previously
created campaign on it. After that, it uses
[`FieldMasks::allSetFieldsOf()`](https://github.com/googleads/google-ads-php/blob/HEAD/src/Google/Ads/GoogleAds/Util/FieldMasks.php#L99) to create a field
mask for the campaign by enumerating all modified fields. Finally, it passes the
returned mask to the campaign operation object.

Note that `FieldMasks::allSetFieldsOf()` is a convenience method for
[`FieldMasks::compare()`](https://github.com/googleads/google-ads-php/blob/HEAD/src/Google/Ads/GoogleAds/Util/FieldMasks.php#L74). It compares your passed object to
an empty object of the same class. For example, in the earlier code, you could
have used `FieldMasks::compare(new Campaign(), $campaign)` instead of
`FieldMasks::allSetFieldsOf($campaign)`.

## Update message fields and their subfields

`MESSAGE` fields can have subfields (such as
[`MaximizeConversions`](https://developers.google.com/google-ads/api/reference/rpc/v26/MaximizeConversions), which includes subfields such as
`target_cpa_micros`, `cpc_bid_ceiling_micros`, and `cpc_bid_floor_micros`), or
they can have none at all (such as [`ManualCpm`](https://developers.google.com/google-ads/api/reference/rpc/v26/ManualCpm)).

### Message fields with no defined subfields

When updating a `MESSAGE` field that is not defined with any subfields, use
`FieldMasks` to generate a field mask, as previously described.

### Message fields with defined subfields

When updating a `MESSAGE` field that is defined with subfields without
explicitly setting any of the subfields on that message, you must manually add
each of the **mutable** `MESSAGE` subfields to the `FieldMask`, similar to the
previous example that created a field mask from scratch.

One common example is updating a campaign's bidding strategy without setting any
of the fields on the new bidding strategy. The following code demonstrates how
to update a campaign to use the [`MaximizeConversions`](https://developers.google.com/google-ads/api/reference/rpc/v26/MaximizeConversions)
bidding strategy without setting any of the subfields on the bidding strategy.

In this case, using the `allSetFieldsOf()` and `compare()` methods of
`FieldMasks` does not achieve the intended goal.

The following code generates a field mask that includes `maximize_conversions`.
However, the Google Ads API doesn't allow this behavior in order to prevent
accidentally clearing fields, and produces a
[`FieldMaskError.FIELD_HAS_SUBFIELDS`](https://developers.google.com/google-ads/api/reference/rpc/v26/FieldMaskErrorEnum.FieldMaskError#field_has_subfields) error.

> [!WARNING]
> **Warning:** The following code produces an error.

    // Creates a campaign with the proper resource name and an empty
    // MaximizeConversions field.
    $campaign = new Campaign([
        'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
        'maximize_conversions' => new MaximizeConversions()
    ]);

    // Constructs an operation, using the FieldMasks' allSetFieldsOf utility to
    // derive the update mask. The field mask includes 'maximize_conversions',
    // which produces a FieldMaskError.FIELD_HAS_SUBFIELDS error.
    $campaignOperation = new CampaignOperation();
    $campaignOperation->setUpdate($campaign);
    $campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));

    // Sends the operation in a mutate request that results in a
    // FieldMaskError.FIELD_HAS_SUBFIELDS error because empty MESSAGE fields cannot
    // be included in a field mask.
    $campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
    $response = $campaignServiceClient->mutateCampaigns(
        MutateCampaignsRequest::build($customerId, [$campaignOperation])
    );

The following code demonstrates how to properly update a campaign to use the
`MaximizeConversions` bidding strategy without setting any of its subfields.

> [!TIP]
> **Success:** The following code successfully updates the campaign bidding strategy.

    // Creates a Campaign object with the proper resource name.
    $campaign = new Campaign([
        'resource_name' => ResourceNames::forCampaign($customerId, $campaignId)
    ]);

    // Creates a field mask from the existing campaign and adds the mutable
    // subfield on the MaximizeConversions bidding strategy to the field mask.
    // Because this field is included in the field mask but excluded from the
    // campaign object, the Google Ads API sets the campaign's bidding strategy
    // to a MaximizeConversions object without any of its subfields set.
    $fieldMask = FieldMasks::allSetFieldsOf($campaign);
    // Only include 'maximize_conversions.target_cpa_micros' in the field mask
    // as it is the only mutable subfield on MaximizeConversions when used as a
    // standard bidding strategy.
    //
    // Learn more about standard and portfolio bidding strategies:
    // https://developers.google.com/google-ads/api/docs/campaigns/bidding/assign-strategies
    $fieldMask->getPaths()[] = 'maximize_conversions.target_cpa_micros';

    // Creates an operation to update the campaign with the specified fields.
    $campaignOperation = new CampaignOperation();
    $campaignOperation->setUpdate($campaign);
    $campaignOperation->setUpdateMask($fieldMask);

## Clear fields

Some fields can be explicitly cleared. Similar to the earlier example, you must
explicitly add these fields to the field mask because `FieldMasks` ignores
Proto3 scalar fields set to their default values (such as `0`, `false`, or
`""`). For example, assume you have a campaign that uses a
`MaximizeConversions` bidding strategy and that the `target_cpa_micros` field
is set with a value that is greater than `0`.

The following code runs; however, `maximize_conversions.target_cpa_micros`
won't be added to the field mask and so no changes are made to the
`target_cpa_micros` field:

> [!WARNING]
> **Warning:** This code doesn't produce an error, but the `target_cpa_micros` field of the `MaximizeConversions` bidding strategy won't be cleared.

    // Creates a campaign with the proper resource name and a MaximizeConversions
    // object with target_cpa_micros set to 0.
    $campaign = new Campaign([
        'resource_name' => ResourceNames::forCampaign($customerId, $campaignId),
        'maximize_conversions' => new MaximizeConversions([
            'target_cpa_micros' => 0
        ]),
        'status' => CampaignStatusEnum\CampaignStatus::PAUSED
    ]);

    // Constructs an operation, using the FieldMasks' allSetFieldsOf utility to
    // derive the update mask. However, the field mask does NOT include
    // 'maximize_conversions.target_cpa_micros'.
    $campaignOperation = new CampaignOperation();
    $campaignOperation->setUpdate($campaign);
    $campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));

    // Sends the operation in a mutate request that succeeds, but does NOT update
    // the 'target_cpa_micros' field because
    // 'maximize_conversions.target_cpa_micros' was not included in the field mask.
    $campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
    $response = $campaignServiceClient->mutateCampaigns(
        MutateCampaignsRequest::build($customerId, [$campaignOperation])
    );

The following code demonstrates how to properly clear the `target_cpa_micros`
field on the `MaximizeConversions` bidding strategy.

> [!TIP]
> **Success:** The following code clears the `target_cpa_micros` field.

    // Creates a Campaign object with the proper resource name.
    $campaign = new Campaign([
        'resource_name' => ResourceNames::forCampaign($customerId, $campaignId)
    ]);

    // Constructs a field mask from the existing campaign and adds the
    // 'maximize_conversions.target_cpa_micros' field to the field mask, which
    // clears this field from the bidding strategy without impacting any other
    // fields on the bidding strategy.
    $fieldMask = FieldMasks::allSetFieldsOf($campaign);
    $fieldMask->getPaths()[] = 'maximize_conversions.target_cpa_micros';

    // Creates an operation to update the campaign with the specified field.
    $campaignOperation = new CampaignOperation();
    $campaignOperation->setUpdate($campaign);
    $campaignOperation->setUpdateMask($fieldMask);

Note that setting a default value does work as intended for fields that are
defined as `optional` in the Google Ads API [protocol buffers](https://github.com/googleapis/googleapis/tree/HEAD/google/ads/googleads). However,
because [`target_cpa_micros`](https://github.com/googleapis/googleapis/tree/HEAD/google/ads/googleads/v26/common/bidding.proto) is not an `optional` field, setting
it to `0` without explicitly adding the path to the field mask does *not* update
the bidding strategy to clear `target_cpa_micros`.

> [!IMPORTANT]
> **Key Point:** If your intention is to clear a field, the safest way is to explicitly add that field to the field mask.