In the Google Ads API, some message fields are used to indicate a choice of
[bidding strategy](https://developers.google.com/google-ads/api/docs/campaigns/bidding/overview) for a [`Campaign`](https://developers.google.com/google-ads/api/reference/rpc/v26/Campaign).
These can be:

- Truly empty messages: For example, [`campaign.manual_cpm`](https://developers.google.com/google-ads/api/fields/v26/campaign#campaign.manual_cpm) has no defined subfields.
- Messages with optional fields: For example, [`campaign.manual_cpc`](https://developers.google.com/google-ads/api/fields/v26/campaign#campaign.manual_cpc.enhanced_cpc_enabled) has the optional subfield [`enhanced_cpc_enabled`](https://developers.google.com/google-ads/api/fields/v26/campaign#campaign.manual_cpc.enhanced_cpc_enabled).

Note that bidding strategy fields on [`Campaign`](https://developers.google.com/google-ads/api/reference/rpc/v26/Campaign) belong
to a `bidding_strategy` `oneof` group. Setting a new bidding strategy such as
`manual_cpm` or `manual_cpc` implicitly clears any previously configured bidding
strategy in that `oneof` group.

To update a primitive field like
[`campaign.name`](https://developers.google.com/google-ads/api/fields/v26/campaign#campaign.name), you set it directly:

    campaign.name = "Test campaign value"

To update a nested message with settable subfields, like `campaign.manual_cpc`
when enabling enhanced CPC, set it as follows:

    campaign.manual_cpc.enhanced_cpc_enabled = True

## Set truly empty messages

To use a bidding strategy like [`manual_cpm`](https://developers.google.com/google-ads/api/fields/v26/campaign#campaign.manual_cpm), which is an empty
message:

1. Get an empty instance of the message type ([`ManualCpm`](https://developers.google.com/google-ads/api/fields/v26/campaign#campaign.manual_cpm)).
2. Use `client.copy_from` to assign this empty instance to the campaign's field.
3. Manually add the field name (`manual_cpm`) to the [`update_mask`](https://developers.google.com/google-ads/api/docs/client-libs/python/field-masks) on the [`CampaignOperation`](https://developers.google.com/google-ads/api/reference/rpc/v26/CampaignOperation). The [field mask helper](https://developers.google.com/google-ads/api/docs/client-libs/python/field-masks#field-mask-helper) cannot automatically detect that an empty message has been explicitly set.

    from google.ads.googleads import util
    from google.ads.googleads.client import GoogleAdsClient
    from google.api_core.protobuf_helpers import field_mask

    client = GoogleAdsClient.load_from_storage()
    # Assume 'campaign' is an existing Campaign object you are updating.

    # 1. Get an empty ManualCpm type.
    empty_cpm = client.get_type("ManualCpm")

    # 2. Copy it to the campaign's manual_cpm field.
    client.copy_from(campaign.manual_cpm, empty_cpm)

    # 3. Create the operation and manually add "manual_cpm" to the update_mask.
    campaign_operation = client.get_type("CampaignOperation")
    client.copy_from(campaign_operation.update, campaign)
    client.copy_from(
        campaign_operation.update_mask,
        field_mask(None, util.convert_proto_plus_to_protobuf(campaign)),
    )
    campaign_operation.update_mask.paths.append("manual_cpm")

    # The resulting proto sent to the API will include:
    # manual_cpm {
    # }

## Set messages with optional subfields

To use [`manual_cpc`](https://developers.google.com/google-ads/api/fields/v26/campaign#campaign.manual_cpc.enhanced_cpc_enabled) as the bidding strategy without enabling
[`enhanced_cpc_enabled`](https://developers.google.com/google-ads/api/fields/v26/campaign#campaign.manual_cpc.enhanced_cpc_enabled), you might try an approach similar to
[`ManualCpm`](https://developers.google.com/google-ads/api/fields/v26/campaign#campaign.manual_cpm). However, because [`ManualCpc`](https://developers.google.com/google-ads/api/fields/v26/campaign#campaign.manual_cpc.enhanced_cpc_enabled) has
subfields, adding `manual_cpc` to the [`update_mask`](https://developers.google.com/google-ads/api/docs/client-libs/python/field-masks) results in a
[`FieldMaskError.FIELD_HAS_SUBFIELDS`](https://developers.google.com/google-ads/api/reference/rpc/v26/FieldMaskErrorEnum.FieldMaskError#field_has_subfields) error. The API
requires more specificity when a message in the mask has subfields.

To correctly set `campaign.manual_cpc` while ensuring `enhanced_cpc_enabled`
remains unset:

1. Instantiate an empty [`ManualCpc`](https://developers.google.com/google-ads/api/fields/v26/campaign#campaign.manual_cpc.enhanced_cpc_enabled) object and copy it into `campaign.manual_cpc` using `client.copy_from`.
2. Manually add the path to each mutable subfield of `ManualCpc` to the [`update_mask`](https://developers.google.com/google-ads/api/docs/client-libs/python/field-masks) on the [`CampaignOperation`](https://developers.google.com/google-ads/api/reference/rpc/v26/CampaignOperation). In this case, the relevant subfield is [`enhanced_cpc_enabled`](https://developers.google.com/google-ads/api/fields/v26/campaign#campaign.manual_cpc.enhanced_cpc_enabled).

    from google.ads.googleads import util
    from google.ads.googleads.client import GoogleAdsClient
    from google.api_core.protobuf_helpers import field_mask

    client = GoogleAdsClient.load_from_storage()
    # Assume 'campaign' is an existing Campaign object you are updating.

    # 1. Copy an empty ManualCpc object into campaign.manual_cpc.
    client.copy_from(campaign.manual_cpc, client.get_type("ManualCpc"))

    # 2. Manually add the subfield path to the update_mask.
    campaign_operation = client.get_type("CampaignOperation")
    client.copy_from(campaign_operation.update, campaign)
    client.copy_from(
        campaign_operation.update_mask,
        field_mask(None, util.convert_proto_plus_to_protobuf(campaign)),
    )

    # For ManualCpc, because it has subfields, you must specify the subfield
    # path in the update_mask. This tells the API you are updating something
    # within manual_cpc. By not setting enhanced_cpc_enabled on the campaign
    # object, it defaults to false.
    campaign_operation.update_mask.paths.append("manual_cpc.enhanced_cpc_enabled")

    # The update_mask paths will include: ['manual_cpc.enhanced_cpc_enabled']
    # This correctly signals to the API that ManualCpc is the chosen strategy,
    # with enhanced_cpc_enabled in its default state.

When sending requests using these patterns, you can verify the payload by
enabling [logging](https://developers.google.com/google-ads/api/docs/client-libs/python/logging) and inspecting the request.