In the Google Ads API, updates are done using a [field mask](https://protobuf.dev/reference/protobuf/google.protobuf/#field-mask). The
field mask (`google.protobuf.FieldMask`) contains a list of field paths in
`snake_case` that you intend to change with the update. Any specified fields
that are not in the field mask are ignored, even if sent to the server.

## FieldMasks utility

The recommended way to generate field masks in the Java client library is to use
the built-in `FieldMasks` utility class, which lets you generate field masks
from a modified object instead of building them from scratch.

Here's an example for updating a campaign:

    // Creates a Campaign object with the proper resource name and any other
    // changes.
    Campaign campaign =
        Campaign.newBuilder()
            .setResourceName(ResourceNames.campaign(customerId, campaignId))
            .setStatus(CampaignStatus.PAUSED)
            .build();

    // Constructs an operation that updates the campaign, using the
    // FieldMasks.allSetFieldsOf utility to derive the update mask. This mask tells
    // the Google Ads API which attributes of the campaign you want to change.
    CampaignOperation operation =
        CampaignOperation.newBuilder()
            .setUpdate(campaign)
            .setUpdateMask(FieldMasks.allSetFieldsOf(campaign))
            .build();

    // Sends the operation in a mutate request.
    MutateCampaignsResponse response =
        campaignServiceClient.mutateCampaigns(
            customerId.toString(), Collections.singletonList(operation));

This example first creates an empty `Campaign` builder and sets its resource
name so that the API knows which campaign is being updated.

The example then calls `FieldMasks.allSetFieldsOf()` on the campaign to
automatically produce a field mask that enumerates all set fields. You can pass
the returned mask directly to the update call.

If you need to work with an existing object and update a few fields, use
`FieldMasks.compare()` as follows:

    // Assumes existingCampaign was retrieved from a previous API call.

    // Creates a new campaign based on the existing campaign and updates the
    // campaign by setting its status to paused.
    Campaign campaignToUpdate =
        existingCampaign.toBuilder()
            .setStatus(CampaignStatus.PAUSED)
            .build();

    // Constructs an operation that updates the campaign, using the
    // FieldMasks.compare utility to derive the update mask. This mask tells the
    // Google Ads API which attributes of the campaign you want to change.
    CampaignOperation operation =
        CampaignOperation.newBuilder()
            .setUpdate(campaignToUpdate)
            .setUpdateMask(FieldMasks.compare(existingCampaign, campaignToUpdate))
            .build();

    // Sends the operation in a mutate request.
    MutateCampaignsResponse response =
        campaignServiceClient.mutateCampaigns(
            customerId.toString(), Collections.singletonList(operation));

To create a field mask from scratch, create a [`FieldMask`](https://developers.google.com/protocol-buffers/docs/reference/java)
builder and add the `snake_case` name of each field you intend to change:

    FieldMask fieldMask =
        FieldMask.newBuilder()
            .addPaths("status")
            .addPaths("name")
            .build();

## 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 has
`target_cpa_micros`, `cpc_bid_ceiling_micros`, and `cpc_bid_floor_micros`), or
they can have no subfields (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 the
`FieldMasks` utility to generate a field mask, as described in the preceding
section.

### Message fields with defined subfields

When updating a `MESSAGE` field that has defined 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 creating a field
mask from scratch.

One common example is updating a campaign's bidding strategy (`oneof` field
`campaign_bidding_strategy`) without setting any of the fields on the new
bidding strategy. The following example 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` alone doesn't achieve the intended goal.

The following example generates a field mask that includes
`maximize_conversions`. However, the Google Ads API doesn't allow top-level message
paths that have subfields in an update mask (to prevent accidentally clearing
subfields) and returns 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 a `FieldMaskError.FIELD_HAS_SUBFIELDS` error.

    // Creates a campaign with the proper resource name and an empty
    // MaximizeConversions field.
    Campaign campaign =
        Campaign.newBuilder()
            .setResourceName(ResourceNames.campaign(customerId, campaignId))
            .setMaximizeConversions(MaximizeConversions.newBuilder().build())
            .build();

    // Constructs an operation using FieldMasks.allSetFieldsOf to derive the update
    // mask. The field mask includes 'maximize_conversions', which produces a
    // FieldMaskError.FIELD_HAS_SUBFIELDS error.
    CampaignOperation operation =
        CampaignOperation.newBuilder()
            .setUpdate(campaign)
            .setUpdateMask(FieldMasks.allSetFieldsOf(campaign))
            .build();

    // Sends the operation in a mutate request that results in a
    // FieldMaskError.FIELD_HAS_SUBFIELDS error because empty MESSAGE fields with
    // subfields cannot be included directly in a field mask.
    MutateCampaignsResponse response =
        campaignServiceClient.mutateCampaigns(
            customerId.toString(), Collections.singletonList(operation));

The following example demonstrates how to properly update a campaign to use the
`MaximizeConversions` bidding strategy without setting any of its subfields.
Learn more about
[assigning standard and portfolio bidding strategies](https://developers.google.com/google-ads/api/docs/campaigns/bidding/assign-strategies).

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

    // Creates a Campaign object with the proper resource name.
    Campaign campaign =
        Campaign.newBuilder()
            .setResourceName(ResourceNames.campaign(customerId, campaignId))
            .build();

    // Creates a field mask from the campaign and adds the mutable subfield
    // ('maximize_conversions.target_cpa_micros') on the MaximizeConversions
    // bidding strategy to the field mask. Because this subfield is included in the
    // field mask while excluded from the campaign object, the Google Ads API
    // switches the campaign's bidding strategy oneof to MaximizeConversions with
    // target_cpa_micros unset.
    FieldMask fieldMask =
        FieldMasks.allSetFieldsOf(campaign).toBuilder()
            .addPaths("maximize_conversions.target_cpa_micros")
            .build();

    // Creates an operation to update the campaign with the specified fields.
    CampaignOperation operation =
        CampaignOperation.newBuilder()
            .setUpdate(campaign)
            .setUpdateMask(fieldMask)
            .build();

## Clear fields

Some fields can be explicitly cleared. Similar to the preceding example, you
must explicitly add these fields to the field mask while leaving them unset on
the message object. 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 greater than `0`.

The following code runs, but `maximize_conversions.target_cpa_micros` won't be
cleared as intended:

> [!WARNING]
> **Warning:** This code doesn't clear `target_cpa_micros` on the `MaximizeConversions` bidding strategy.

    // Creates a campaign with the proper resource name and a MaximizeConversions
    // object with target_cpa_micros set to 0L.
    Campaign campaign =
        Campaign.newBuilder()
            .setResourceName(ResourceNames.campaign(customerId, campaignId))
            .setMaximizeConversions(
                MaximizeConversions.newBuilder().setTargetCpaMicros(0L).build())
            .setStatus(CampaignStatus.PAUSED)
            .build();

    // Constructs an operation using FieldMasks.allSetFieldsOf to derive the
    // update mask.
    CampaignOperation operation =
        CampaignOperation.newBuilder()
            .setUpdate(campaign)
            .setUpdateMask(FieldMasks.allSetFieldsOf(campaign))
            .build();

    // Sends the operation in a mutate request that does not clear the field
    // cleanly.
    MutateCampaignsResponse response =
        campaignServiceClient.mutateCampaigns(
            customerId.toString(), Collections.singletonList(operation));

The next example demonstrates how to properly clear the `target_cpa_micros`
field on the `MaximizeConversions` bidding strategy.

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

    // Creates a Campaign object with the proper resource name.
    Campaign campaign =
        Campaign.newBuilder()
            .setResourceName(ResourceNames.campaign(customerId, campaignId))
            .build();

    // Constructs a field mask from the 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 fieldMask =
        FieldMasks.allSetFieldsOf(campaign).toBuilder()
            .addPaths("maximize_conversions.target_cpa_micros")
            .build();

    // Creates an operation to update the campaign with the specified field.
    CampaignOperation operation =
        CampaignOperation.newBuilder()
            .setUpdate(campaign)
            .setUpdateMask(fieldMask)
            .build();

> [!IMPORTANT]
> **Key Point:** If your intention is to clear a field, explicitly add that field's path to the `FieldMask` and leave the field unset on the resource object.